mirror of https://github.com/dapr/docs.git
Merge branch 'v1.5' into feature/pubsub_pulsar0901
This commit is contained in:
commit
7bef63b9d7
|
@ -3,11 +3,11 @@ name: Azure Static Web App Root
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- v1.3
|
||||
- v1.4
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, closed]
|
||||
branches:
|
||||
- v1.3
|
||||
- v1.4
|
||||
|
||||
jobs:
|
||||
build_and_deploy_job:
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
name: Azure Static Web App v1.3
|
||||
name: Azure Static Web App v1.4
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v1.3
|
||||
- v1.5
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, closed]
|
||||
branches:
|
||||
- v1.3
|
||||
- v1.5
|
||||
|
||||
jobs:
|
||||
build_and_deploy_job:
|
||||
|
@ -27,7 +27,7 @@ jobs:
|
|||
HUGO_ENV: production
|
||||
HUGO_VERSION: "0.74.3"
|
||||
with:
|
||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_3 }}
|
||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_5 }}
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
|
||||
skip_deploy_on_missing_secrets: true
|
||||
action: "upload"
|
||||
|
@ -48,6 +48,6 @@ jobs:
|
|||
id: closepullrequest
|
||||
uses: Azure/static-web-apps-deploy@v0.0.1-preview
|
||||
with:
|
||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_3 }}
|
||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_5 }}
|
||||
skip_deploy_on_missing_secrets: true
|
||||
action: "close"
|
|
@ -20,3 +20,6 @@
|
|||
[submodule "sdkdocs/java"]
|
||||
path = sdkdocs/java
|
||||
url = https://github.com/dapr/java-sdk.git
|
||||
[submodule "sdkdocs/js"]
|
||||
path = sdkdocs/js
|
||||
url = https://github.com/dapr/js-sdk.git
|
||||
|
|
|
@ -14,8 +14,8 @@ The following branches are currently maintained:
|
|||
|
||||
| Branch | Website | Description |
|
||||
|--------|---------|-------------|
|
||||
| [v1.3](https://github.com/dapr/docs) (primary) | https://docs.dapr.io | Latest Dapr release documentation. Typo fixes, clarifications, and most documentation goes here.
|
||||
| [v1.4](https://github.com/dapr/docs/tree/v1.4) (pre-release) | https://v1-4.docs.dapr.io/ | Pre-release documentation. Doc updates that are only applicable to v1.4+ go here.
|
||||
| [v1.4](https://github.com/dapr/docs) (primary) | https://docs.dapr.io | Latest Dapr release documentation. Typo fixes, clarifications, and most documentation goes here.
|
||||
| [v1.5](https://github.com/dapr/docs/tree/v1.5) (pre-release) | https://v1-5.docs.dapr.io/ | Pre-release documentation. Doc updates that are only applicable to v1.5+ go here.
|
||||
|
||||
For more information visit the [Dapr branch structure](https://docs.dapr.io/contributing/contributing-docs/#branch-guidance) document.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Site Configuration
|
||||
baseURL = "https://docs.dapr.io/"
|
||||
baseURL = "https://v1-5.docs.dapr.io/"
|
||||
title = "Dapr Docs"
|
||||
theme = "docsy"
|
||||
disableFastRender = true
|
||||
|
@ -87,6 +87,14 @@ id = "UA-149338238-3"
|
|||
source = "../sdkdocs/java/daprdocs/content/en/java-sdk-contributing"
|
||||
target = "content/contributing/"
|
||||
lang = "en"
|
||||
[[module.mounts]]
|
||||
source = "../sdkdocs/js/daprdocs/content/en/js-sdk-docs"
|
||||
target = "content/developing-applications/sdks/js"
|
||||
lang = "en"
|
||||
[[module.mounts]]
|
||||
source = "../sdkdocs/js/daprdocs/content/en/js-sdk-contributing"
|
||||
target = "content/contributing/"
|
||||
lang = "en"
|
||||
|
||||
[[module.mounts]]
|
||||
source = "../translations/docs-zh/content/zh-hans"
|
||||
|
@ -149,20 +157,23 @@ offlineSearch = false
|
|||
github_repo = "https://github.com/dapr/docs"
|
||||
github_project_repo = "https://github.com/dapr/dapr"
|
||||
github_subdir = "daprdocs"
|
||||
github_branch = "v1.3"
|
||||
github_branch = "v1.5"
|
||||
|
||||
# Versioning
|
||||
version_menu = "v1.3 (latest)"
|
||||
version = "v1.3"
|
||||
version_menu = "v1.5 (preview)"
|
||||
version = "v1.5"
|
||||
archived_version = false
|
||||
url_latest_version = "https://docs.dapr.io"
|
||||
|
||||
[[params.versions]]
|
||||
version = "v1.4 (preview)"
|
||||
url = "https://v1-4.docs.dapr.io"
|
||||
[[params.versions]]
|
||||
version = "v1.3 (latest)"
|
||||
version = "v1.5 (preview)"
|
||||
url = "#"
|
||||
[[params.versions]]
|
||||
version = "v1.4 (latest)"
|
||||
url = "https://docs.dapr.io"
|
||||
[[params.versions]]
|
||||
version = "v1.3"
|
||||
url = "https://v1-3.docs.dapr.io"
|
||||
[[params.versions]]
|
||||
version = "v1.2"
|
||||
url = "https://v1-2.docs.dapr.io"
|
||||
|
@ -190,6 +201,10 @@ url_latest_version = "https://docs.dapr.io"
|
|||
sidebar_menu_compact = true
|
||||
navbar_logo = true
|
||||
sidebar_search_disable = true
|
||||
[params.ui.feedback]
|
||||
enable = true
|
||||
yes = '<b>Glad to hear it!</b> Please <a href="https://github.com/dapr/docs/issues/new/choose">tell us how we can improve</a>.'
|
||||
no = '<b>Sorry to hear that.</b> Please <a href="https://github.com/dapr/docs/issues/new/choose">tell us how we can improve</a>.'
|
||||
|
||||
# Links
|
||||
## End user relevant links. These will show up on left side of footer and in the community page if you have one.
|
||||
|
|
|
@ -3,20 +3,39 @@ type: docs
|
|||
no_list: true
|
||||
---
|
||||
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/daprcon.png" alt="DaprCon logo" width=40>
|
||||
<b> Join us for DaprCon on October 19th-20th, 2021!</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
The first ever DaprCon will take place October 19th-20th, 2021 virtually! Tune in for free and attend technical sessions, panels and real world examples from the community on building applications with Dapr! <br></br><i><b>Learn more >></b></i>
|
||||
</p>
|
||||
<a href="https://blog.dapr.io/posts/2021/10/05/join-us-for-daprcon-october-19th-20th-2021/" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br></br>
|
||||
# <img src="/images/home-title.png" alt="Dapr Docs" width=400>
|
||||
|
||||
Welcome to the Dapr documentation site!
|
||||
|
||||
### Sections
|
||||
|
||||
{{% alert title="What is Dapr?" color="primary" %}}
|
||||
Dapr is a portable, event-driven runtime that makes it easy for any developer to build resilient,
|
||||
stateless and stateful applications that run on the cloud and edge and embraces the diversity of
|
||||
languages and developer frameworks. Leveraging the benefits of a sidecar architecture, Dapr helps
|
||||
you tackle the challenges that come with building microservices and keeps your code platform agnostic.
|
||||
{{< button text="Get started" page="getting-started" >}}
|
||||
{{% /alert %}}
|
||||
|
||||
|
||||
### Start developing with Dapr
|
||||
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Concepts</b></h5>
|
||||
<p class="card-text">Learn about Dapr, including its main features and capabilities.</p>
|
||||
<a href="{{< ref concepts >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Getting started</b></h5>
|
||||
|
@ -24,6 +43,26 @@ Welcome to the Dapr documentation site!
|
|||
<a href="{{< ref getting-started >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Quickstarts</b></h5>
|
||||
<p class="card-text">A collection of tutorials with code samples to get you started quickly with Dapr.</p>
|
||||
<a href="{{< ref quickstarts >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Concepts</b></h5>
|
||||
<p class="card-text">Learn about Dapr, including its main features and capabilities.</p>
|
||||
<a href="{{< ref concepts >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
### Learn more about Dapr
|
||||
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Developing applications</b></h5>
|
||||
|
@ -31,9 +70,13 @@ Welcome to the Dapr documentation site!
|
|||
<a href="{{< ref developing-applications >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Building blocks</b></h5>
|
||||
<p class="card-text">Capabilities that solve common development challenges for distributed applications.</p>
|
||||
<a href="{{< ref building-blocks-concept >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Operations</b></h5>
|
||||
|
@ -41,6 +84,12 @@ Welcome to the Dapr documentation site!
|
|||
<a href="{{< ref operations >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
### Additional info
|
||||
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Reference</b></h5>
|
||||
|
@ -58,64 +107,100 @@ Welcome to the Dapr documentation site!
|
|||
</div>
|
||||
|
||||
|
||||
### Tooling
|
||||
### Tooling and resources
|
||||
|
||||
<div class="media">
|
||||
<a class="pr-1" href="{{< ref ides >}}">
|
||||
<img class="mr-3" src="/images/homepage/vscode.svg" alt="Visual studio code icon" width=40>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>IDE Integrations</b></h5>
|
||||
<p>Learn how to get up and running with Dapr in your preferred integrated development environment.</p>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/vscode.svg" alt="Visual studio code icon" width=40>
|
||||
<b>IDE Integrations</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn how to get up and running with Dapr in your preferred integrated development environment.
|
||||
</p>
|
||||
<a href="{{< ref ides >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media">
|
||||
<a class="pr-1" href="{{< ref sdks >}}">
|
||||
<img class="mr-3" src="/images/homepage/code.svg" alt="Code icon" width=40>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Language SDKs</b></h5>
|
||||
<p>Create Dapr applications in your preferred language using the Dapr SDKs.</p>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-3" href="{{< ref dotnet >}}">
|
||||
<br>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/code.svg" alt="Code icon" width=40>
|
||||
<b>Language SDKs</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Create Dapr applications in your preferred language using the Dapr SDKs.
|
||||
</p>
|
||||
<a href="{{< ref sdks >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/dotnet.png" alt=".NET logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>.NET</b></h5>
|
||||
</div>
|
||||
<b>.NET</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the .NET SDK.
|
||||
</p>
|
||||
<a href="{{< ref dotnet >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-3" href="{{< ref python >}}">
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/python.png" alt="Python logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Python</b></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-4" href="{{< ref sdks >}}">
|
||||
<img src="/images/homepage/java.png" alt="Java logo" width=20>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Java</b></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-4" href="{{< ref go >}}">
|
||||
<img src="/images/homepage/golang.svg" alt="Go logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Go</b></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-4" href="{{< ref php >}}">
|
||||
<img src="/images/homepage/php.png" alt="PHP logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>PHP</b></h5>
|
||||
</div>
|
||||
<b>Python</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the Python SDK.
|
||||
</p>
|
||||
<a href="{{< ref python >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/javalang.png" alt="Java logo" width=30>
|
||||
<b>Java</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the Java SDK.
|
||||
</p>
|
||||
<a href="{{< ref java >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/golang.svg" alt="Go logo" width=30>
|
||||
<b>Go</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the Go SDK.
|
||||
</p>
|
||||
<a href="{{< ref go >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/php.png" alt="PHP logo" width=30>
|
||||
<b>PHP</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the PHP SDK.
|
||||
</p>
|
||||
<a href="{{< ref php >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -4,4 +4,13 @@ title: "Dapr concepts"
|
|||
linkTitle: "Concepts"
|
||||
weight: 10
|
||||
description: "Learn about Dapr including its main features and capabilities"
|
||||
---
|
||||
---
|
||||
|
||||
Welcome to the Dapr concepts guide!
|
||||
|
||||
|
||||
{{% alert title="Getting started with Dapr" color="primary" %}}
|
||||
If you are ready to jump in and start developing with Dapr, please
|
||||
visit the [getting started section]({{<ref getting-started>}}).
|
||||
{{< button text="Install Dapr" page="getting-started" >}}
|
||||
{{% /alert %}}
|
|
@ -49,3 +49,9 @@ For a detailed list of all available arguments run `daprd --help` or see this [t
|
|||
```bash
|
||||
daprd --app-id myapp --enable-metrics
|
||||
```
|
||||
|
||||
5. Listen to IPv4 and IPv6 loopback only
|
||||
|
||||
```bash
|
||||
daprd --app-id myapp --dapr-listen-addresses '127.0.0.1,[::1]'
|
||||
```
|
||||
|
|
|
@ -35,7 +35,7 @@ Every actor is defined as an instance of an actor type, identical to the way an
|
|||
|
||||
## Actor lifetime
|
||||
|
||||
Dapr actors are virtual, meaning that their lifetime is not tied to their in-memory representation. As a result, they do not need to be explicitly created or destroyed. The Dapr actors runtime automatically activates an actor the first time it receives a request for that actor ID. If an actor is not used for a period of time, the Dapr Actors runtime garbage-collects the in-memory object. It will also maintain knowledge of the actor's existence should it need to be reactivated later.
|
||||
Dapr actors are virtual, meaning that their lifetime is not tied to their in-memory representation. As a result, they do not need to be explicitly created or destroyed. The Dapr actor runtime automatically activates an actor the first time it receives a request for that actor ID. If an actor is not used for a period of time, the Dapr actor runtime garbage-collects the in-memory object. It will also maintain knowledge of the actor's existence should it need to be reactivated later.
|
||||
|
||||
Invocation of actor methods and reminders reset the idle time, e.g. reminder firing will keep the actor active. Actor reminders fire whether an actor is active or inactive, if fired for inactive actor, it will activate the actor first. Actor timers do not reset the idle time, so timer firing will not keep the actor active. Timers only fire while the actor is active.
|
||||
|
||||
|
@ -77,11 +77,13 @@ POST/GET/PUT/DELETE http://localhost:3500/v1.0/actors/<actorType>/<actorId>/<met
|
|||
|
||||
You can provide any data for the actor method in the request body, and the response for the request would be in the response body which is the data from actor call.
|
||||
|
||||
Another, and perhaps more convenient, way of interacting with actors is via SDKs. Dapr currently supports actors SDKs in [.NET]({{< ref "dotnet-actors" >}}), [Java]({{< ref "java#actors" >}}), and [Python]({{< ref "python-actor" >}}).
|
||||
|
||||
Refer to [Dapr Actor Features]({{< ref howto-actors.md >}}) for more details.
|
||||
|
||||
### Concurrency
|
||||
|
||||
The Dapr Actors runtime provides a simple turn-based access model for accessing actor methods. This means that no more than one thread can be active inside an actor object's code at any time. Turn-based access greatly simplifies concurrent systems as there is no need for synchronization mechanisms for data access. It also means systems must be designed with special considerations for the single-threaded access nature of each actor instance.
|
||||
The Dapr actor runtime provides a simple turn-based access model for accessing actor methods. This means that no more than one thread can be active inside an actor object's code at any time. Turn-based access greatly simplifies concurrent systems as there is no need for synchronization mechanisms for data access. It also means systems must be designed with special considerations for the single-threaded access nature of each actor instance.
|
||||
|
||||
A single actor instance cannot process more than one request at a time. An actor instance can cause a throughput bottleneck if it is expected to handle concurrent requests.
|
||||
|
||||
|
@ -94,9 +96,9 @@ As an enhancement to the base actors in dapr, reentrancy can now be enabled as a
|
|||
|
||||
### Turn-based access
|
||||
|
||||
A turn consists of the complete execution of an actor method in response to a request from other actors or clients, or the complete execution of a timer/reminder callback. Even though these methods and callbacks are asynchronous, the Dapr Actors runtime does not interleave them. A turn must be fully finished before a new turn is allowed. In other words, an actor method or timer/reminder callback that is currently executing must be fully finished before a new call to a method or callback is allowed. A method or callback is considered to have finished if the execution has returned from the method or callback and the task returned by the method or callback has finished. It is worth emphasizing that turn-based concurrency is respected even across different methods, timers, and callbacks.
|
||||
A turn consists of the complete execution of an actor method in response to a request from other actors or clients, or the complete execution of a timer/reminder callback. Even though these methods and callbacks are asynchronous, the Dapr actor runtime does not interleave them. A turn must be fully finished before a new turn is allowed. In other words, an actor method or timer/reminder callback that is currently executing must be fully finished before a new call to a method or callback is allowed. A method or callback is considered to have finished if the execution has returned from the method or callback and the task returned by the method or callback has finished. It is worth emphasizing that turn-based concurrency is respected even across different methods, timers, and callbacks.
|
||||
|
||||
The Dapr actors runtime enforces turn-based concurrency by acquiring a per-actor lock at the beginning of a turn and releasing the lock at the end of the turn. Thus, turn-based concurrency is enforced on a per-actor basis and not across actors. Actor methods and timer/reminder callbacks can execute simultaneously on behalf of different actors.
|
||||
The Dapr actor runtime enforces turn-based concurrency by acquiring a per-actor lock at the beginning of a turn and releasing the lock at the end of the turn. Thus, turn-based concurrency is enforced on a per-actor basis and not across actors. Actor methods and timer/reminder callbacks can execute simultaneously on behalf of different actors.
|
||||
|
||||
The following example illustrates the above concepts. Consider an actor type that implements two asynchronous methods (say, Method1 and Method2), a timer, and a reminder. The diagram below shows an example of a timeline for the execution of these methods and callbacks on behalf of two actors (ActorId1 and ActorId2) that belong to this actor type.
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ weight: 20
|
|||
description: Learn more about the actor pattern
|
||||
---
|
||||
|
||||
The Dapr actors runtime provides support for [virtual actors]({{< ref actors-overview.md >}}) through following capabilities:
|
||||
The Dapr actor runtime provides support for [virtual actors]({{< ref actors-overview.md >}}) through following capabilities:
|
||||
|
||||
## Actor method invocation
|
||||
|
||||
You can interact with Dapr to invoke the actor method by calling HTTP/gRPC endpoint
|
||||
You can interact with Dapr to invoke the actor method by calling HTTP/gRPC endpoint.
|
||||
|
||||
```html
|
||||
POST/GET/PUT/DELETE http://localhost:3500/v1.0/actors/<actorType>/<actorId>/method/<method>
|
||||
|
@ -20,6 +20,8 @@ You can provide any data for the actor method in the request body and the respon
|
|||
|
||||
Refer [api spec]({{< ref "actors_api.md#invoke-actor-method" >}}) for more details.
|
||||
|
||||
Alternatively, you can use the Dapr SDK in [.NET]({{< ref "dotnet-actors" >}}), [Java]({{< ref "java#actors" >}}), or [Python]({{< ref "python-actor" >}}).
|
||||
|
||||
## Actor state management
|
||||
|
||||
Actors can save state reliably using state management capability.
|
||||
|
@ -31,27 +33,62 @@ To use actors, your state store must support multi-item transactions. This mean
|
|||
|
||||
Actors can schedule periodic work on themselves by registering either timers or reminders.
|
||||
|
||||
The functionality of timers and reminders is very similar. The main difference is that Dapr actor runtime is not retaining any information about timers after deactivation, while persisting the information about reminders using Dapr actor state provider.
|
||||
|
||||
This distintcion allows users to trade off between light-weight but stateless timers vs. more resource-demanding but stateful reminders.
|
||||
|
||||
The scheduling configuration of timers and reminders is identical, as summarized below:
|
||||
|
||||
---
|
||||
`dueTime` is an optional parameter that sets time at which or time interval before the callback is invoked for the first time. If `dueTime` is omitted, the callback is invoked immediately after timer/reminder registration.
|
||||
|
||||
Supported formats:
|
||||
- RFC3339 date format, e.g. `2020-10-02T15:00:00Z`
|
||||
- time.Duration format, e.g. `2h30m`
|
||||
- [ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) format, e.g. `PT2H30M`
|
||||
|
||||
---
|
||||
`period` is an optional parameter that sets time interval between two consecutive callback invocations. When specified in `ISO 8601-1 duration` format, you can also configure the number of repetition in order to limit the total number of callback invocations.
|
||||
If `period` is omitted, the callback will be invoked only once.
|
||||
|
||||
Supported formats:
|
||||
- time.Duration format, e.g. `2h30m`
|
||||
- [ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) format, e.g. `PT2H30M`, `R5/PT1M30S`
|
||||
|
||||
---
|
||||
`ttl` is an optional parameter that sets time at which or time interval after which the timer/reminder will be expired and deleted. If `ttl` is omitted, no restrictions are applied.
|
||||
|
||||
Supported formats:
|
||||
* RFC3339 date format, e.g. `2020-10-02T15:00:00Z`
|
||||
* time.Duration format, e.g. `2h30m`
|
||||
* [ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) format. Example: `PT2H30M`
|
||||
|
||||
---
|
||||
The actor runtime validates correctess of the scheduling configuration and returns error on invalid input.
|
||||
|
||||
When you specify both the number of repetitions in `period` as well as `ttl`, the timer/reminder will be stopped when either condition is met.
|
||||
|
||||
### Actor timers
|
||||
|
||||
You can register a callback on actor to be executed based on a timer.
|
||||
|
||||
The Dapr actor runtime ensures that the callback methods respect the turn-based concurrency guarantees.This means that no other actor methods or timer/reminder callbacks will be in progress until this callback completes execution.
|
||||
The Dapr actor runtime ensures that the callback methods respect the turn-based concurrency guarantees. This means that no other actor methods or timer/reminder callbacks will be in progress until this callback completes execution.
|
||||
|
||||
The next period of the timer starts after the callback completes execution. This implies that the timer is stopped while the callback is executing and is started when the callback finishes.
|
||||
The Dapr actor runtime saves changes made to the actor's state when the callback finishes. If an error occurs in saving the state, that actor object is deactivated and a new instance will be activated.
|
||||
|
||||
The Dapr actors runtime saves changes made to the actor's state when the callback finishes. If an error occurs in saving the state, that actor object is deactivated and a new instance will be activated.
|
||||
All timers are stopped when the actor is deactivated as part of garbage collection. No timer callbacks are invoked after that. Also, the Dapr actor runtime does not retain any information about the timers that were running before deactivation. It is up to the actor to register any timers that it needs when it is reactivated in the future.
|
||||
|
||||
All timers are stopped when the actor is deactivated as part of garbage collection. No timer callbacks are invoked after that. Also, the Dapr actors runtime does not retain any information about the timers that were running before deactivation. It is up to the actor to register any timers that it needs when it is reactivated in the future.
|
||||
|
||||
You can create a timer for an actor by calling the HTTP/gRPC request to Dapr.
|
||||
You can create a timer for an actor by calling the HTTP/gRPC request to Dapr as shown below, or via Dapr SDK.
|
||||
|
||||
```md
|
||||
POST/PUT http://localhost:3500/v1.0/actors/<actorType>/<actorId>/timers/<name>
|
||||
```
|
||||
|
||||
The timer `duetime` and callback are specified in the request body. The due time represents when the timer will first fire after registration. The `period` represents how often the timer fires after that. A due time of 0 means to fire immediately. Negative due times and negative periods are invalid.
|
||||
**Examples**
|
||||
|
||||
The following request body configures a timer with a `dueTime` of 9 seconds and a `period` of 3 seconds. This means it will first fire after 9 seconds, then every 3 seconds after that.
|
||||
The timer parameters are specified in the request body.
|
||||
|
||||
The following request body configures a timer with a `dueTime` of 9 seconds and a `period` of 3 seconds. This means it will first fire after 9 seconds, then every 3 seconds after that.
|
||||
```json
|
||||
{
|
||||
"dueTime":"0h0m9s0ms",
|
||||
|
@ -59,11 +96,27 @@ The following request body configures a timer with a `dueTime` of 9 seconds and
|
|||
}
|
||||
```
|
||||
|
||||
The following request body configures a timer with a `dueTime` 0 seconds and a `period` of 3 seconds. This means it fires immediately after registration, then every 3 seconds after that.
|
||||
The following request body configures a timer with a `period` of 3 seconds (in ISO 8601 duration format). It also limits the number of invocations to 10. This means it will fire 10 times: first, immediately after registration, then every 3 seconds after that.
|
||||
```json
|
||||
{
|
||||
"dueTime":"0h0m0s0ms",
|
||||
"period":"0h0m3s0ms"
|
||||
"period":"R10/PT3S",
|
||||
}
|
||||
```
|
||||
|
||||
The following request body configures a timer with a `period` of 3 seconds (in ISO 8601 duration format) and a `ttl` of 20 seconds. This means it fires immediately after registration, then every 3 seconds after that for the duration of 20 seconds.
|
||||
```json
|
||||
{
|
||||
"period":"PT3S",
|
||||
"ttl":"20s"
|
||||
}
|
||||
```
|
||||
|
||||
The following request body configures a timer with a `dueTime` of 10 seconds, a `period` of 3 seconds, and a `ttl` of 10 seconds. It also limits the number of invocations to 4. This means it will first fire after 10 seconds, then every 3 seconds after that for the duration of 10 seconds, but no more than 4 times in total.
|
||||
```json
|
||||
{
|
||||
"dueTime":"10s",
|
||||
"period":"R4/PT3S",
|
||||
"ttl":"10s"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -77,69 +130,15 @@ Refer [api spec]({{< ref "actors_api.md#invoke-timer" >}}) for more details.
|
|||
|
||||
### Actor reminders
|
||||
|
||||
Reminders are a mechanism to trigger *persistent* callbacks on an actor at specified times. Their functionality is similar to timers. But unlike timers, reminders are triggered under all circumstances until the actor explicitly unregisters them or the actor is explicitly deleted or the number in invocations is exhausted. Specifically, reminders are triggered across actor deactivations and failovers because the Dapr actors runtime persists the information about the actors' reminders using Dapr actor state provider.
|
||||
Reminders are a mechanism to trigger *persistent* callbacks on an actor at specified times. Their functionality is similar to timers. But unlike timers, reminders are triggered under all circumstances until the actor explicitly unregisters them or the actor is explicitly deleted or the number in invocations is exhausted. Specifically, reminders are triggered across actor deactivations and failovers because the Dapr actor runtime persists the information about the actors' reminders using Dapr actor state provider.
|
||||
|
||||
You can create a persistent reminder for an actor by calling the Http/gRPC request to Dapr.
|
||||
You can create a persistent reminder for an actor by calling the HTTP/gRPC request to Dapr as shown below, or via Dapr SDK.
|
||||
|
||||
```md
|
||||
POST/PUT http://localhost:3500/v1.0/actors/<actorType>/<actorId>/reminders/<name>
|
||||
```
|
||||
|
||||
The reminder `duetime` and callback can be specified in the request body. The due time represents when the reminder first fires after registration. The `period` represents how often the reminder will fire after that. A due time of 0 means to fire immediately. Negative due times and negative periods are invalid. To register a reminder that fires only once, set the period to an empty string.
|
||||
|
||||
The following request body configures a reminder with a `dueTime` 9 seconds and a `period` of 3 seconds. This means it will first fire after 9 seconds, then every 3 seconds after that.
|
||||
```json
|
||||
{
|
||||
"dueTime":"0h0m9s0ms",
|
||||
"period":"0h0m3s0ms"
|
||||
}
|
||||
```
|
||||
|
||||
The following request body configures a reminder with a `dueTime` 0 seconds and a `period` of 3 seconds. This means it will fire immediately after registration, then every 3 seconds after that.
|
||||
```json
|
||||
{
|
||||
"dueTime":"0h0m0s0ms",
|
||||
"period":"0h0m3s0ms"
|
||||
}
|
||||
```
|
||||
|
||||
The following request body configures a reminder with a `dueTime` 15 seconds and a `period` of empty string. This means it will first fire after 15 seconds, then never fire again.
|
||||
```json
|
||||
{
|
||||
"dueTime":"0h0m15s0ms",
|
||||
"period":""
|
||||
}
|
||||
```
|
||||
|
||||
[ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) can also be used to specify `period`. The following request body configures a reminder with a `dueTime` 0 seconds an `period` of 15 seconds.
|
||||
```json
|
||||
{
|
||||
"dueTime":"0h0m0s0ms",
|
||||
"period":"P0Y0M0W0DT0H0M15S"
|
||||
}
|
||||
```
|
||||
The designators for zero are optional and the above `period` can be simplified to `PT15S`.
|
||||
ISO 8601 specifies multiple recurrence formats but only the duration format is currently supported.
|
||||
|
||||
#### Reminders with repetitions
|
||||
|
||||
When configured with ISO 8601 durations, the `period` column also allows to specify number of times a reminder can run. The following request body will create a reminder that will execute for 5 number of times with a period of 15 seconds.
|
||||
```json
|
||||
{
|
||||
"dueTime":"0h0m0s0ms",
|
||||
"period":"R5/PT15S"
|
||||
}
|
||||
```
|
||||
|
||||
The number of repetitions i.e. the number of times the reminder is run should be a positive number.
|
||||
|
||||
**Example**
|
||||
|
||||
Watch this [video](https://www.youtube.com/watch?v=B_vkXqptpXY&t=1002s) for more information on using ISO 861 for Reminders
|
||||
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/B_vkXqptpXY?start=1003" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
The request structure for reminders is identical to those of actors. Please refer to the [actor timers examples]({{< ref "#actor-timers" >}}).
|
||||
|
||||
#### Retrieve actor reminder
|
||||
|
||||
|
@ -161,7 +160,7 @@ Refer [api spec]({{< ref "actors_api.md#invoke-reminder" >}}) for more details.
|
|||
|
||||
## Actor runtime configuration
|
||||
|
||||
You can configure the Dapr Actors runtime configuration to modify the default runtime behavior.
|
||||
You can configure the Dapr actor runtime configuration to modify the default runtime behavior.
|
||||
|
||||
### Configuration parameters
|
||||
- `actorIdleTimeout` - The timeout before deactivating an idle actor. Checks for timeouts occur every `actorScanInterval` interval. **Default: 60 minutes**
|
||||
|
|
|
@ -91,6 +91,20 @@ In order to tell Dapr that the event wasn't processed correctly in your applicat
|
|||
res.status(500).send()
|
||||
```
|
||||
|
||||
### Specifying a custom route
|
||||
|
||||
By default, incoming events will be sent to an HTTP endpoint that corresponds to the name of the input binding.
|
||||
You can override this by setting the following metadata property:
|
||||
|
||||
```yaml
|
||||
name: mybinding
|
||||
spec:
|
||||
type: binding.rabbitmq
|
||||
metadata:
|
||||
- name: route
|
||||
value: /onevent
|
||||
```
|
||||
|
||||
### Event delivery Guarantees
|
||||
Event delivery guarantees are controlled by the binding implementation. Depending on the binding implementation, the event delivery can be exactly once or at least once.
|
||||
|
||||
|
|
|
@ -489,6 +489,7 @@ Read about content types [here](#content-types), and about the [Cloud Events mes
|
|||
## Next steps
|
||||
|
||||
- Try the [Pub/Sub quickstart sample](https://github.com/dapr/quickstarts/tree/master/pub-sub)
|
||||
- Learn about [PubSub routing]({{< ref howto-route-messages >}})
|
||||
- Learn about [topic scoping]({{< ref pubsub-scopes.md >}})
|
||||
- Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}})
|
||||
- Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}})
|
||||
|
|
|
@ -0,0 +1,519 @@
|
|||
---
|
||||
type: docs
|
||||
title: "How-To: Route messages to different event handlers"
|
||||
linkTitle: "How-To: Route events"
|
||||
weight: 2100
|
||||
description: "Learn how to route messages from a topic to different event handlers based on CloudEvent fields"
|
||||
---
|
||||
|
||||
{{% alert title="Preview feature" color="warning" %}}
|
||||
Pub/Sub message routing is currently in [preview]({{< ref preview-features.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
## Introduction
|
||||
|
||||
[Content-based routing](https://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html) is a messaging pattern that utilizes a DSL instead of imperative application code. PubSub routing is an implementation of this pattern that allows developers to use expressions to route [CloudEvents](https://cloudevents.io) based on their contents to different URIs/paths and event handlers in your application. If no route matches, then an optional default route is used. This becomes useful as your applications expands to support multiple event versions, or special cases. Routing can be implemented with code; however, keeping routing rules external from the application can improve portability.
|
||||
|
||||
This feature is available to both the declarative and programmatic subscription approaches.
|
||||
|
||||
## Enable message routing
|
||||
|
||||
This is a preview feature. To enable it, add the `PubSub.Routing` feature entry to your application configuration like so:
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Configuration
|
||||
metadata:
|
||||
name: pubsubroutingconfig
|
||||
spec:
|
||||
features:
|
||||
- name: PubSub.Routing
|
||||
enabled: true
|
||||
```
|
||||
Learn more about enabling [preview features]({{<ref preview-features>}}).
|
||||
## Declarative subscription
|
||||
|
||||
For declarative subscriptions, you must use `dapr.io/v2alpha1` as the `apiVersion`. Here is an example of `subscriptions.yaml` using routing.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v2alpha1
|
||||
kind: Subscription
|
||||
metadata:
|
||||
name: myevent-subscription
|
||||
spec:
|
||||
pubsubname: pubsub
|
||||
topic: inventory
|
||||
routes:
|
||||
rules:
|
||||
- match: event.type == "widget"
|
||||
path: /widgets
|
||||
- match: event.type == "gadget"
|
||||
path: /gadgets
|
||||
default: /products
|
||||
scopes:
|
||||
- app1
|
||||
- app2
|
||||
```
|
||||
|
||||
## Programmatic subscription
|
||||
|
||||
Alternatively, the programattic approach varies slightly in that the `routes` structure is returned instead of `route`. The JSON structure matches the declarative YAML.
|
||||
|
||||
{{< tabs Python Node "C#" Go PHP>}}
|
||||
|
||||
{{% codetab %}}
|
||||
```python
|
||||
import flask
|
||||
from flask import request, jsonify
|
||||
from flask_cors import CORS
|
||||
import json
|
||||
import sys
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
CORS(app)
|
||||
|
||||
@app.route('/dapr/subscribe', methods=['GET'])
|
||||
def subscribe():
|
||||
subscriptions = [
|
||||
{
|
||||
'pubsubname': 'pubsub',
|
||||
'topic': 'inventory',
|
||||
'routes': {
|
||||
'rules': [
|
||||
{
|
||||
'match': 'event.type == "widget"',
|
||||
'path': '/widgets'
|
||||
},
|
||||
{
|
||||
'match': 'event.type == "gadget"',
|
||||
'path': '/gadgets'
|
||||
},
|
||||
],
|
||||
'default': '/products'
|
||||
}
|
||||
}]
|
||||
return jsonify(subscriptions)
|
||||
|
||||
@app.route('/products', methods=['POST'])
|
||||
def ds_subscriber():
|
||||
print(request.json, flush=True)
|
||||
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
|
||||
app.run()
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```javascript
|
||||
const express = require('express')
|
||||
const bodyParser = require('body-parser')
|
||||
const app = express()
|
||||
app.use(bodyParser.json({ type: 'application/*+json' }));
|
||||
|
||||
const port = 3000
|
||||
|
||||
app.get('/dapr/subscribe', (req, res) => {
|
||||
res.json([
|
||||
{
|
||||
pubsubname: "pubsub",
|
||||
topic: "inventory",
|
||||
routes: {
|
||||
rules: [
|
||||
{
|
||||
match: 'event.type == "widget"',
|
||||
path: '/widgets'
|
||||
},
|
||||
{
|
||||
match: 'event.type == "gadget"',
|
||||
path: '/gadgets'
|
||||
},
|
||||
],
|
||||
default: '/products'
|
||||
}
|
||||
}
|
||||
]);
|
||||
})
|
||||
|
||||
app.post('/products', (req, res) => {
|
||||
console.log(req.body);
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
app.listen(port, () => console.log(`consumer app listening on port ${port}!`))
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```csharp
|
||||
[Topic("pubsub", "inventory", "event.type ==\"widget\"", 1)]
|
||||
[HttpPost("widgets")]
|
||||
public async Task<ActionResult<Stock>> HandleWidget(Widget widget, [FromServices] DaprClient daprClient)
|
||||
{
|
||||
// Logic
|
||||
return stock;
|
||||
}
|
||||
|
||||
[Topic("pubsub", "inventory", "event.type ==\"gadget\"", 2)]
|
||||
[HttpPost("gadgets")]
|
||||
public async Task<ActionResult<Stock>> HandleGadget(Gadget gadget, [FromServices] DaprClient daprClient)
|
||||
{
|
||||
// Logic
|
||||
return stock;
|
||||
}
|
||||
|
||||
[Topic("pubsub", "inventory")]
|
||||
[HttpPost("products")]
|
||||
public async Task<ActionResult<Stock>> HandleProduct(Product product, [FromServices] DaprClient daprClient)
|
||||
{
|
||||
// Logic
|
||||
return stock;
|
||||
}
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```golang
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
const appPort = 3000
|
||||
|
||||
type subscription struct {
|
||||
PubsubName string `json:"pubsubname"`
|
||||
Topic string `json:"topic"`
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
Routes routes `json:"routes"`
|
||||
}
|
||||
|
||||
type routes struct {
|
||||
Rules []rule `json:"rules,omitempty"`
|
||||
Default string `json:"default,omitempty"`
|
||||
}
|
||||
|
||||
type rule struct {
|
||||
Match string `json:"match"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// This handles /dapr/subscribe
|
||||
func configureSubscribeHandler(w http.ResponseWriter, _ *http.Request) {
|
||||
t := []subscription{
|
||||
{
|
||||
PubsubName: "pubsub",
|
||||
Topic: "inventory",
|
||||
Routes: routes{
|
||||
Rules: []rule{
|
||||
{
|
||||
Match: `event.type == "widget"`,
|
||||
Path: "/widgets",
|
||||
},
|
||||
{
|
||||
Match: `event.type == "gadget"`,
|
||||
Path: "/gadgets",
|
||||
},
|
||||
},
|
||||
Default: "/products",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(t)
|
||||
}
|
||||
|
||||
func main() {
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
router.HandleFunc("/dapr/subscribe", configureSubscribeHandler).Methods("GET")
|
||||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", appPort), router))
|
||||
}
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```php
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/vendor/autoload.php';
|
||||
|
||||
$app = \Dapr\App::create(configure: fn(\DI\ContainerBuilder $builder) => $builder->addDefinitions(['dapr.subscriptions' => [
|
||||
new \Dapr\PubSub\Subscription(pubsubname: 'pubsub', topic: 'inventory', routes: (
|
||||
rules: => [
|
||||
('match': 'event.type == "widget"', path: '/widgets'),
|
||||
('match': 'event.type == "gadget"', path: '/gadgets'),
|
||||
]
|
||||
default: '/products')),
|
||||
]]));
|
||||
$app->post('/products', function(
|
||||
#[\Dapr\Attributes\FromBody]
|
||||
\Dapr\PubSub\CloudEvent $cloudEvent,
|
||||
\Psr\Log\LoggerInterface $logger
|
||||
) {
|
||||
$logger->alert('Received event: {event}', ['event' => $cloudEvent]);
|
||||
return ['status' => 'SUCCESS'];
|
||||
}
|
||||
);
|
||||
$app->start();
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
## Common Expression Language (CEL)
|
||||
|
||||
In these examples, depending on the type of the event (`event.type`), the application will be called on `/widgets`, `/gadgets` or `/products`. The expressions are written as [Common Expression Language (CEL)](https://github.com/google/cel-spec) where `event` represents the cloud event. Any of the attributes from the [CloudEvents core specification](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#required-attributes) can be referenced in the expression.
|
||||
|
||||
### Example expressions
|
||||
|
||||
Match "important" messages
|
||||
|
||||
```javascript
|
||||
has(event.data.important) && event.data.important == true
|
||||
```
|
||||
|
||||
Match deposits greater than $10000
|
||||
|
||||
```javascript
|
||||
event.type == "deposit" && event.data.amount > 10000
|
||||
```
|
||||
|
||||
Match multiple versions of a message
|
||||
|
||||
```javascript
|
||||
event.type == "mymessage.v1"
|
||||
```
|
||||
```javascript
|
||||
event.type == "mymessage.v2"
|
||||
```
|
||||
|
||||
## CloudEvent attributes
|
||||
|
||||
For reference, the following attributes are from the CloudEvents specification.
|
||||
|
||||
### Event Data
|
||||
|
||||
#### data
|
||||
|
||||
As defined by the term Data, CloudEvents MAY include domain-specific information about the occurrence. When present, this information will be encapsulated within `data`.
|
||||
|
||||
- Description: The event payload. This specification does not place any restriction on the type of this information. It is encoded into a media format which is specified by the `datacontenttype` attribute (e.g. application/json), and adheres to the `dataschema` format when those respective attributes are present.
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
|
||||
{{% alert title="Limitation" color="warning" %}}
|
||||
Currently, it is only possible to access the attributes inside data if it is nested JSON values and not JSON escaped in a string.
|
||||
{{% /alert %}}
|
||||
|
||||
### REQUIRED Attributes
|
||||
|
||||
The following attributes are REQUIRED to be present in all CloudEvents:
|
||||
|
||||
#### id
|
||||
|
||||
- Type: `String`
|
||||
- Description: Identifies the event. Producers MUST ensure that `source` + `id`
|
||||
is unique for each distinct event. If a duplicate event is re-sent (e.g. due
|
||||
to a network error) it MAY have the same `id`. Consumers MAY assume that
|
||||
Events with identical `source` and `id` are duplicates.
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty string
|
||||
- MUST be unique within the scope of the producer
|
||||
- Examples:
|
||||
- An event counter maintained by the producer
|
||||
- A UUID
|
||||
|
||||
#### source
|
||||
|
||||
- Type: `URI-reference`
|
||||
- Description: Identifies the context in which an event happened. Often this
|
||||
will include information such as the type of the event source, the
|
||||
organization publishing the event or the process that produced the event. The
|
||||
exact syntax and semantics behind the data encoded in the URI is defined by
|
||||
the event producer.
|
||||
|
||||
Producers MUST ensure that `source` + `id` is unique for each distinct event.
|
||||
|
||||
An application MAY assign a unique `source` to each distinct producer, which
|
||||
makes it easy to produce unique IDs since no other producer will have the same
|
||||
source. The application MAY use UUIDs, URNs, DNS authorities or an
|
||||
application-specific scheme to create unique `source` identifiers.
|
||||
|
||||
A source MAY include more than one producer. In that case the producers MUST
|
||||
collaborate to ensure that `source` + `id` is unique for each distinct event.
|
||||
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty URI-reference
|
||||
- An absolute URI is RECOMMENDED
|
||||
- Examples
|
||||
- Internet-wide unique URI with a DNS authority.
|
||||
- https://github.com/cloudevents
|
||||
- mailto:cncf-wg-serverless@lists.cncf.io
|
||||
- Universally-unique URN with a UUID:
|
||||
- urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66
|
||||
- Application-specific identifiers
|
||||
- /cloudevents/spec/pull/123
|
||||
- /sensors/tn-1234567/alerts
|
||||
- 1-555-123-4567
|
||||
|
||||
#### specversion
|
||||
|
||||
- Type: `String`
|
||||
- Description: The version of the CloudEvents specification which the event
|
||||
uses. This enables the interpretation of the context. Compliant event
|
||||
producers MUST use a value of `1.0` when referring to this version of the
|
||||
specification.
|
||||
|
||||
Currently, this attribute will only have the 'major' and 'minor' version
|
||||
numbers included in it. This allows for 'patch' changes to the specification
|
||||
to be made without changing this property's value in the serialization.
|
||||
Note: for 'release candidate' releases a suffix might be used for testing
|
||||
purposes.
|
||||
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty string
|
||||
|
||||
#### type
|
||||
|
||||
- Type: `String`
|
||||
- Description: This attribute contains a value describing the type of event
|
||||
related to the originating occurrence. Often this attribute is used for
|
||||
routing, observability, policy enforcement, etc. The format of this is
|
||||
producer defined and might include information such as the version of the
|
||||
`type` - see
|
||||
[Versioning of CloudEvents in the Primer](https://github.com/cloudevents/spec/blob/v1.0.1/primer.md#versioning-of-cloudevents)
|
||||
for more information.
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty string
|
||||
- SHOULD be prefixed with a reverse-DNS name. The prefixed domain dictates the
|
||||
organization which defines the semantics of this event type.
|
||||
- Examples
|
||||
- com.github.pull_request.opened
|
||||
- com.example.object.deleted.v2
|
||||
|
||||
### OPTIONAL Attributes
|
||||
|
||||
The following attributes are OPTIONAL to appear in CloudEvents. See the
|
||||
[Notational Conventions](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#notational-conventions) section for more information
|
||||
on the definition of OPTIONAL.
|
||||
|
||||
#### datacontenttype
|
||||
|
||||
- Type: `String` per [RFC 2046](https://tools.ietf.org/html/rfc2046)
|
||||
- Description: Content type of `data` value. This attribute enables `data` to
|
||||
carry any type of content, whereby format and encoding might differ from that
|
||||
of the chosen event format. For example, an event rendered using the
|
||||
[JSON envelope](https://github.com/cloudevents/spec/blob/v1.0.1/json-format.md#3-envelope) format might carry an XML payload
|
||||
in `data`, and the consumer is informed by this attribute being set to
|
||||
"application/xml". The rules for how `data` content is rendered for different
|
||||
`datacontenttype` values are defined in the event format specifications; for
|
||||
example, the JSON event format defines the relationship in
|
||||
[section 3.1](https://github.com/cloudevents/spec/blob/v1.0.1/json-format.md#31-handling-of-data).
|
||||
|
||||
For some binary mode protocol bindings, this field is directly mapped to the
|
||||
respective protocol's content-type metadata property. Normative rules for the
|
||||
binary mode and the content-type metadata mapping can be found in the
|
||||
respective protocol.
|
||||
|
||||
In some event formats the `datacontenttype` attribute MAY be omitted. For
|
||||
example, if a JSON format event has no `datacontenttype` attribute, then it is
|
||||
implied that the `data` is a JSON value conforming to the "application/json"
|
||||
media type. In other words: a JSON-format event with no `datacontenttype` is
|
||||
exactly equivalent to one with `datacontenttype="application/json"`.
|
||||
|
||||
When translating an event message with no `datacontenttype` attribute to a
|
||||
different format or protocol binding, the target `datacontenttype` SHOULD be
|
||||
set explicitly to the implied `datacontenttype` of the source.
|
||||
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST adhere to the format specified in
|
||||
[RFC 2046](https://tools.ietf.org/html/rfc2046)
|
||||
- For Media Type examples see
|
||||
[IANA Media Types](http://www.iana.org/assignments/media-types/media-types.xhtml)
|
||||
|
||||
#### dataschema
|
||||
|
||||
- Type: `URI`
|
||||
- Description: Identifies the schema that `data` adheres to. Incompatible
|
||||
changes to the schema SHOULD be reflected by a different URI. See
|
||||
[Versioning of CloudEvents in the Primer](https://github.com/cloudevents/spec/blob/v1.0.1/primer.md#versioning-of-cloudevents)
|
||||
for more information.
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST be a non-empty URI
|
||||
|
||||
#### subject
|
||||
|
||||
- Type: `String`
|
||||
- Description: This describes the subject of the event in the context of the
|
||||
event producer (identified by `source`). In publish-subscribe scenarios, a
|
||||
subscriber will typically subscribe to events emitted by a `source`, but the
|
||||
`source` identifier alone might not be sufficient as a qualifier for any
|
||||
specific event if the `source` context has internal sub-structure.
|
||||
|
||||
Identifying the subject of the event in context metadata (opposed to only in
|
||||
the `data` payload) is particularly helpful in generic subscription filtering
|
||||
scenarios where middleware is unable to interpret the `data` content. In the
|
||||
above example, the subscriber might only be interested in blobs with names
|
||||
ending with '.jpg' or '.jpeg' and the `subject` attribute allows for
|
||||
constructing a simple and efficient string-suffix filter for that subset of
|
||||
events.
|
||||
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST be a non-empty string
|
||||
- Example:
|
||||
- A subscriber might register interest for when new blobs are created inside a
|
||||
blob-storage container. In this case, the event `source` identifies the
|
||||
subscription scope (storage container), the `type` identifies the "blob
|
||||
created" event, and the `id` uniquely identifies the event instance to
|
||||
distinguish separate occurrences of a same-named blob having been created;
|
||||
the name of the newly created blob is carried in `subject`:
|
||||
- `source`: https://example.com/storage/tenant/container
|
||||
- `subject`: mynewfile.jpg
|
||||
|
||||
#### time
|
||||
|
||||
- Type: `Timestamp`
|
||||
- Description: Timestamp of when the occurrence happened. If the time of the
|
||||
occurrence cannot be determined then this attribute MAY be set to some other
|
||||
time (such as the current time) by the CloudEvents producer, however all
|
||||
producers for the same `source` MUST be consistent in this respect. In other
|
||||
words, either they all use the actual time of the occurrence or they all use
|
||||
the same algorithm to determine the value used.
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST adhere to the format specified in
|
||||
[RFC 3339](https://tools.ietf.org/html/rfc3339)
|
||||
|
||||
{{% alert title="Limitation" color="warning" %}}
|
||||
Currently, comparisons to time (e.g. before or after "now") are not supported.
|
||||
{{% /alert %}}
|
||||
|
||||
## Community call demo
|
||||
|
||||
Watch [this video](https://www.youtube.com/watch?v=QqJgRmbH82I&t=1063s) on how to use message routing with pub/sub:
|
||||
|
||||
<p class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="688" height="430" src="https://www.youtube.com/embed/QqJgRmbH82I?start=1063" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</p>
|
||||
|
||||
## Next steps
|
||||
|
||||
- Try the [Pub/Sub routing sample](https://github.com/dapr/samples/tree/master/pub-sub-routing)
|
||||
- Learn about [topic scoping]({{< ref pubsub-scopes.md >}})
|
||||
- Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}})
|
||||
- Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}})
|
||||
- List of [pub/sub components]({{< ref setup-pubsub >}})
|
||||
- Read the [API reference]({{< ref pubsub_api.md >}})
|
|
@ -111,6 +111,32 @@ curl http://localhost:3500/v1.0/invoke/cart/method/add -X DELETE
|
|||
```
|
||||
|
||||
Dapr puts any payload returned by the called service in the HTTP response's body.
|
||||
|
||||
### Additional URL formats
|
||||
|
||||
In order to avoid changing URL paths as much as possible, Dapr provides the following ways to call the service invocation API:
|
||||
|
||||
|
||||
1. Change the address in the URL to `localhost:<dapr-http-port>`.
|
||||
2. Add a `dapr-app-id` header to specify the ID of the target service, or alternatively pass the ID via HTTP Basic Auth: `http://dapr-app-id:<service-id>@localhost:3500/path`.
|
||||
|
||||
For example, the following command
|
||||
```bash
|
||||
curl http://localhost:3500/v1.0/invoke/cart/method/add
|
||||
```
|
||||
|
||||
is equivalent to:
|
||||
|
||||
```bash
|
||||
curl -H 'dapr-app-id: cart' 'http://localhost:3500/add' -X POST
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```bash
|
||||
curl 'http://dapr-app-id:cart@localhost:3500/add' -X POST
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
|
|
@ -5,9 +5,12 @@ linkTitle: "How-To: Invoke with gRPC"
|
|||
description: "Call between services using service invocation"
|
||||
weight: 3000
|
||||
---
|
||||
{{% alert title="Preview feature" color="warning" %}}
|
||||
gRPC proxying is currently in [preview]({{< ref preview-features.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
This article describe how to use Dapr to connect services using gRPC.
|
||||
By using Dapr's gRPC proxying capability, you can use your existing proto based gRPC services and have the traffic go through the Dapr sidecar. Doing so yields the following [Dapr Service Invocation]({{< ref service-invocation-overview.md >}}) benefits to developers:
|
||||
By using Dapr's gRPC proxying capability, you can use your existing proto based gRPC services and have the traffic go through the Dapr sidecar. Doing so yields the following [Dapr service invocation]({{< ref service-invocation-overview.md >}}) benefits to developers:
|
||||
|
||||
1. Mutual authentication
|
||||
2. Tracing
|
||||
|
@ -170,7 +173,7 @@ var call = client.SayHello(new HelloRequest { Name = "Darth Nihilus" }, metadata
|
|||
|
||||
{{% codetab %}}
|
||||
```python
|
||||
metadata = (('dapr-app-id', 'server'))
|
||||
metadata = (('dapr-app-id', 'server'),)
|
||||
response = stub.SayHello(request={ name: 'Darth Revan' }, metadata=metadata)
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
@ -305,3 +308,10 @@ For more information on tracing and logs see the [observability]({{< ref observa
|
|||
* [Service invocation overview]({{< ref service-invocation-overview.md >}})
|
||||
* [Service invocation API specification]({{< ref service_invocation_api.md >}})
|
||||
* [gRPC proxying community call video](https://youtu.be/B_vkXqptpXY?t=70)
|
||||
|
||||
## Community call demo
|
||||
Watch this [video](https://youtu.be/B_vkXqptpXY?t=69) on how to use Dapr's gRPC proxying capability:
|
||||
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/B_vkXqptpXY?start=69" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
|
@ -0,0 +1,92 @@
|
|||
---
|
||||
type: docs
|
||||
title: "How-To: Encrypt application state"
|
||||
linkTitle: "How-To: Encrypt state"
|
||||
weight: 450
|
||||
description: "Automatically encrypt state and manage key rotations"
|
||||
|
||||
---
|
||||
|
||||
{{% alert title="Preview feature" color="warning" %}}
|
||||
State store encryption is currently in [preview]({{< ref preview-features.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
## Introduction
|
||||
|
||||
Application state often needs to get encrypted at rest to provide stronger security in enterprise workloads or regulated environments. Dapr offers automatic client side encryption based on [AES256](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard).
|
||||
|
||||
In addition to automatic encryption, Dapr supports primary and secondary encryption keys to make it easier for developers and ops teams to enable a key rotation strategy.
|
||||
This feature is supported by all Dapr state stores.
|
||||
|
||||
The encryption keys are fetched from a secret, and cannot be supplied as plaintext values on the `metadata` section.
|
||||
|
||||
## Enabling automatic encryption
|
||||
|
||||
1. Enable the state encryption preview feature using a standard [Dapr Configuration]({{< ref configuration-overview.md >}}):
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Configuration
|
||||
metadata:
|
||||
name: stateconfig
|
||||
spec:
|
||||
features:
|
||||
- name: State.Encryption
|
||||
enabled: true
|
||||
```
|
||||
|
||||
2. Add the following `metadata` section to any Dapr supported state store:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
- name: primaryEncryptionKey
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: mykey # key is optional.
|
||||
```
|
||||
|
||||
For example, this is the full YAML of a Redis encrypted state store
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: statestore
|
||||
spec:
|
||||
type: state.redis
|
||||
version: v1
|
||||
metadata:
|
||||
- name: redisHost
|
||||
value: localhost:6379
|
||||
- name: redisPassword
|
||||
value: ""
|
||||
- name: primaryEncryptionKey
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: mykey
|
||||
```
|
||||
|
||||
You now have a Dapr state store that's configured to fetch the encryption key from a secret named `mysecret`, containing the actual encryption key in a key named `mykey`.
|
||||
The actual encryption key *must* be an AES256 encryption key. Dapr will error and exit if the encryption key is invalid.
|
||||
|
||||
*Note that the secret store does not have to support keys*
|
||||
|
||||
## Key rotation
|
||||
|
||||
To support key rotation, Dapr provides a way to specify a secondary encryption key:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
- name: primaryEncryptionKey
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: mykey
|
||||
- name: secondaryEncryptionKey
|
||||
secretKeyRef:
|
||||
name: mysecret2
|
||||
key: mykey2
|
||||
```
|
||||
|
||||
When Dapr starts, it will fetch the secrets containing the encryption keys listed in the `metadata` section. Dapr knows which state item has been encrypted with which key automatically, as it appends the `secretKeyRef.name` field to the end of the actual state key.
|
||||
|
||||
To rotate a key, simply change the `primaryEncryptionKey` to point to a secret containing your new key, and move the old primary encryption key to the `secondaryEncryptionKey`. New data will be encrypted using the new key, and old data that's retrieved will be decrypted using the secondary key. Any updates to data items encrypted using the old key will be re-encrypted using the new key.
|
|
@ -50,6 +50,12 @@ For stores that don't natively support ETags, it's expected that the correspondi
|
|||
|
||||
Read the [API reference]({{< ref state_api.md >}}) to learn how to set concurrency options.
|
||||
|
||||
### Automatic encryption
|
||||
|
||||
Dapr supports automatic client encryption of application state with support for key rotations. This is a preview feature and it is supported on all Dapr state stores.
|
||||
|
||||
For more info, read the [How-To: Encrypt application state]({{< ref howto-encrypt-state.md >}}) section.
|
||||
|
||||
### Consistency
|
||||
|
||||
Dapr supports both **strong consistency** and **eventual consistency**, with eventual consistency as the default behavior.
|
||||
|
@ -104,6 +110,7 @@ The API for state management can be found in the [state management API reference
|
|||
* [How-To: Save and get state]({{< ref howto-get-save-state.md >}})
|
||||
* [How-To: Build a stateful service]({{< ref howto-stateful-service.md >}})
|
||||
* [How-To: Share state between applications]({{< ref howto-share-state.md >}})
|
||||
* [How-To: Encrypt application state]({{< ref howto-encrypt-state.md >}})
|
||||
* Try out the [hello world quickstart](https://github.com/dapr/quickstarts/blob/master/hello-world/README.md) which shows how to use state management or try the samples in the [Dapr SDKs]({{< ref sdks >}})
|
||||
* List of [state store components]({{< ref supported-state-stores.md >}})
|
||||
* Read the [state management API reference]({{< ref state_api.md >}})
|
||||
|
|
|
@ -0,0 +1,407 @@
|
|||
---
|
||||
type: docs
|
||||
title: "Authenticating to Azure"
|
||||
linkTitle: "Authenticating to Azure"
|
||||
description: "How to authenticate Azure components using Azure AD and/or Managed Identities"
|
||||
aliases:
|
||||
- "/operations/components/setup-secret-store/supported-secret-stores/azure-keyvault-managed-identity/"
|
||||
- "/reference/components-reference/supported-secret-stores/azure-keyvault-managed-identity/"
|
||||
---
|
||||
|
||||
## Common Azure authentication layer
|
||||
|
||||
Certain Azure components for Dapr offer support for the *common Azure authentication layer*, which enables applications to access data stored in Azure resources by authenticating with Azure AD. Thanks to this, administrators can leverage all the benefits of fine-tuned permissions with RBAC (Role-Based Access Control), and applications running on certain Azure services such as Azure VMs, Azure Kubernetes Service, or many Azure platform services can leverage [Managed Service Identities (MSI)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview).
|
||||
|
||||
Some Azure components offer alternative authentication methods, such as systems based on "master keys" or "shared keys". Whenever possible, it is recommended that you authenticate your Dapr components using Azure AD for increased security and ease of management, as well as for the ability to leverage MSI if your app is running on supported Azure services.
|
||||
|
||||
> Currently, only a subset of Azure components for Dapr offer support for this authentication method. Over time, support will be expanded to all other Azure components for Dapr. You can track the progress of the work, component-by-component, on [this issue](https://github.com/dapr/components-contrib/issues/1103).
|
||||
|
||||
### About authentication with Azure AD
|
||||
|
||||
Azure AD is Azure's identity and access management (IAM) solution, which is used to authenticate and authorize users and services.
|
||||
|
||||
Azure AD is built on top of open standards such OAuth 2.0, which allows services (applications) to obtain access tokens to make requests to Azure services, including Azure Storage, Azure Key Vault, Cosmos DB, etc. In the Azure terminology, an application is also called a "Service Principal".
|
||||
|
||||
Many of the services listed above also support authentication using other systems, such as "master keys" or "shared keys". Although those are always valid methods to authenticate your application (and Dapr continues to support them, as explained in each component's reference page), using Azure AD when possible offers various benefits, including:
|
||||
|
||||
- The ability to leverage Managed Service Identities, which allow your application to authenticate with Azure AD, and obtain an access token to make requests to Azure services, without the need to use any credential. When your application is running on a supported Azure service (including, but not limited to, Azure VMs, Azure Kubernetes Service, Azure Web Apps, etc), an identity for your application can be assigned at the infrastructure level.
|
||||
This way, your code does not have to deal with credentials of any kind, removing the challenge of safely managing credentials, allowing greater separation of concerns between development and operations teams and reducing the number of people with access to credentials, and lastly simplifying operational aspects–especially when multiple environments are used.
|
||||
- Using RBAC (Role-Based Access Control) with supported services (such as Azure Storage and Cosmos DB), permissions given to an application can be fine-tuned, for example allowing restricting access to a subset of data or making it read-only.
|
||||
- Better auditing for access.
|
||||
- Ability to authenticate using certificates (optional).
|
||||
|
||||
## Credentials metadata fields
|
||||
|
||||
To authenticate with Azure AD, you will need to add the following credentials as values in the metadata for your Dapr component (read the next section for how to create them). There are multiple options depending on the way you have chosen to pass the credentials to your Dapr service.
|
||||
|
||||
**Authenticating using client credentials:**
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|---------------------|----------|--------------------------------------|----------------------------------------------|
|
||||
| `azureTenantId` | Y | ID of the Azure AD tenant | `"cd4b2887-304c-47e1-b4d5-65447fdd542b"` |
|
||||
| `azureClientId` | Y | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
|
||||
| `azureClientSecret` | Y | Client secret (application password) | `"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"` |
|
||||
|
||||
When running on Kubernetes, you can also use references to Kubernetes secrets for any or all of the values above.
|
||||
|
||||
**Authenticating using a PFX certificate:**
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|--------|--------|--------|--------|
|
||||
| `azureTenantId` | Y | ID of the Azure AD tenant | `"cd4b2887-304c-47e1-b4d5-65447fdd542b"` |
|
||||
| `azureClientId` | Y | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
|
||||
| `azureCertificate` | One of `azureCertificate` and `azureCertificateFile` | Certificate and private key (in PFX/PKCS#12 format) | `"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----` |
|
||||
| `azureCertificateFile` | One of `azureCertificate` and `azureCertificateFile` | Path to the PFX/PKCS#12 file containing the certificate and private key | `"/path/to/file.pem"` |
|
||||
| `azureCertificatePassword` | N | Password for the certificate if encrypted | `"password"` |
|
||||
|
||||
When running on Kubernetes, you can also use references to Kubernetes secrets for any or all of the values above.
|
||||
|
||||
**Authenticating with Managed Service Identities (MSI):**
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|-----------------|----------|----------------------------|------------------------------------------|
|
||||
| `azureClientId` | N | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
|
||||
|
||||
Using MSI you're not required to specify any value, although you may optionally pass `azureClientId` if needed.
|
||||
|
||||
### Aliases
|
||||
|
||||
For backwards-compatibility reasons, the following values in the metadata are supported as aliases, although their use is discouraged.
|
||||
|
||||
| Metadata key | Aliases (supported but deprecated) |
|
||||
|----------------------------|------------------------------------|
|
||||
| `azureTenantId` | `spnTenantId`, `tenantId` |
|
||||
| `azureClientId` | `spnClientId`, `clientId` |
|
||||
| `azureClientSecret` | `spnClientSecret`, `clientSecret` |
|
||||
| `azureCertificate` | `spnCertificate` |
|
||||
| `azureCertificateFile` | `spnCertificateFile` |
|
||||
| `azureCertificatePassword` | `spnCertificatePassword` |
|
||||
|
||||
## Generating a new Azure AD application and Service Principal
|
||||
|
||||
To start, create a new Azure AD application, which will also be used as Service Principal.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- [Azure Subscription](https://azure.microsoft.com/free/)
|
||||
- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
|
||||
- [jq](https://stedolan.github.io/jq/download/)
|
||||
- OpenSSL (included by default on all Linux and macOS systems, as well as on WSL)
|
||||
- The scripts below are optimized for a bash or zsh shell
|
||||
|
||||
> If you haven't already, start by logging in to Azure using the Azure CLI:
|
||||
>
|
||||
> ```sh
|
||||
> # Log in Azure
|
||||
> az login
|
||||
> # Set your default subscription
|
||||
> az account set -s [your subscription id]
|
||||
> ```
|
||||
|
||||
### Creating an Azure AD application
|
||||
|
||||
First, create the Azure AD application with:
|
||||
|
||||
```sh
|
||||
# Friendly name for the application / Service Principal
|
||||
APP_NAME="dapr-application"
|
||||
|
||||
# Create the app
|
||||
APP_ID=$(az ad app create \
|
||||
--display-name "${APP_NAME}" \
|
||||
--available-to-other-tenants false \
|
||||
--oauth2-allow-implicit-flow false \
|
||||
| jq -r .appId)
|
||||
```
|
||||
|
||||
{{< tabs "Client secret" "Certificate">}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
To create a **client secret**, then run this command. This will generate a random password based on the base64 charset and 40-characters long. Additionally, it will make the password valid for 2 years, before it will need to be rotated:
|
||||
|
||||
```sh
|
||||
az ad app credential reset \
|
||||
--id "${APP_ID}" \
|
||||
--years 2 \
|
||||
--password $(openssl rand -base64 30)
|
||||
```
|
||||
|
||||
The ouput of the command above will be similar to this:
|
||||
|
||||
```json
|
||||
{
|
||||
"appId": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
|
||||
"name": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
|
||||
"password": "Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E",
|
||||
"tenant": "cd4b2887-304c-47e1-b4d5-65447fdd542b"
|
||||
}
|
||||
```
|
||||
|
||||
Take note of the values above, which you'll need to use in your Dapr components' metadata, to allow Dapr to authenticate with Azure:
|
||||
|
||||
- `appId` is the value for `azureClientId`
|
||||
- `password` is the value for `azureClientSecret` (this was randomly-generated)
|
||||
- `tenant` is the value for `azureTenantId`
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
If you'd rather use a **PFX (PKCS#12) certificate**, run this command which will create a self-signed certificate:
|
||||
|
||||
```sh
|
||||
az ad app credential reset \
|
||||
--id "${APP_ID}" \
|
||||
--create-cert
|
||||
```
|
||||
|
||||
> Note: self-signed certificates are recommended for development only. For production, you should use certificates signed by a CA and imported with the `--cert` flag.
|
||||
|
||||
The output of the command above should look like:
|
||||
|
||||
```json
|
||||
{
|
||||
"appId": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
|
||||
"fileWithCertAndPrivateKey": "/Users/alessandro/tmpgtdgibk4.pem",
|
||||
"name": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
|
||||
"password": null,
|
||||
"tenant": "cd4b2887-304c-47e1-b4d5-65447fdd542b"
|
||||
}
|
||||
```
|
||||
|
||||
Take note of the values above, which you'll need to use in your Dapr components' metadata:
|
||||
|
||||
- `appId` is the value for `azureClientId`
|
||||
- `tenant` is the value for `azureTenantId`
|
||||
- The self-signed PFX certificate and private key are written in the file at the path specified in `fileWithCertAndPrivateKey`.
|
||||
Use the contents of that file as `azureCertificate` (or write it to a file on the server and use `azureCertificateFile`)
|
||||
|
||||
> While the generated file has the `.pem` extension, it contains a certificate and private key encoded as PFX (PKCS#12).
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
### Creating a Service Principal
|
||||
|
||||
Once you have created an Azure AD application, create a Service Principal for that application, which will allow us to grant it access to Azure resources. Run:
|
||||
|
||||
```sh
|
||||
SERVICE_PRINCIPAL_ID=$(az ad sp create \
|
||||
--id "${APP_ID}" \
|
||||
| jq -r .objectId)
|
||||
echo "Service Principal ID: ${SERVICE_PRINCIPAL_ID}"
|
||||
```
|
||||
|
||||
The output will be similar to:
|
||||
|
||||
```text
|
||||
Service Principal ID: 1d0ccf05-5427-4b5e-8eb4-005ac5f9f163
|
||||
```
|
||||
|
||||
Note that the value above is the ID of the **Service Principal** which is different from the ID of application in Azure AD (client ID)! The former is defined within an Azure tenant and is used to grant access to Azure resources to an application. The client ID instead is used by your application to authenticate. To sum things up:
|
||||
|
||||
- You'll use the client ID in Dapr manifests to configure authentication with Azure services
|
||||
- You'll use the Service Principal ID to grant permissions to an application to access Azure resources
|
||||
|
||||
Keep in mind that the Service Principal that was just created does not have access to any Azure resource by default. Access will need to be granted to each resource as needed, as documented in the docs for the components.
|
||||
|
||||
> Note: this step is different from the [official documentation](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli) as the short-hand commands included there create a Service Principal that has broad read-write access to all Azure resources in your subscription.
|
||||
> Not only doing that would grant our Service Principal more access than you are likely going to desire, but this also applies only to the Azure management plane (Azure Resource Manager, or ARM), which is irrelevant for Dapr anyways (all Azure components are designed to interact with the data plane of various services, and not ARM).
|
||||
|
||||
### Example usage in a Dapr component
|
||||
|
||||
In this example, you will set up an Azure Key Vault secret store component that uses Azure AD to authenticate.
|
||||
|
||||
{{< tabs "Self-Hosted" "Kubernetes">}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
To use a **client secret**, create a file called `azurekeyvault.yaml` in the components directory, filling in with the details from the above setup process:
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureClientSecret
|
||||
value : "[your_client_secret]"
|
||||
```
|
||||
|
||||
If you want to use a **certificate** saved on the local disk, instead, use:
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureCertificateFile
|
||||
value : "[pfx_certificate_file_fully_qualified_local_path]"
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
In Kubernetes, you store the client secret or the certificate into the Kubernetes Secret Store and then refer to those in the YAML file.
|
||||
|
||||
To use a **client secret**:
|
||||
|
||||
1. Create a Kubernetes secret using the following command:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic [your_k8s_secret_name] --from-literal=[your_k8s_secret_key]=[your_client_secret]
|
||||
```
|
||||
|
||||
- `[your_client_secret]` is the application's client secret as generated above
|
||||
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
|
||||
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
|
||||
|
||||
2. Create an `azurekeyvault.yaml` component file.
|
||||
|
||||
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the client secret stored in the Kubernetes secret store.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureClientSecret
|
||||
secretKeyRef:
|
||||
name: "[your_k8s_secret_name]"
|
||||
key: "[your_k8s_secret_key]"
|
||||
auth:
|
||||
secretStore: kubernetes
|
||||
```
|
||||
|
||||
3. Apply the `azurekeyvault.yaml` component:
|
||||
|
||||
```bash
|
||||
kubectl apply -f azurekeyvault.yaml
|
||||
```
|
||||
|
||||
To use a **certificate**:
|
||||
|
||||
1. Create a Kubernetes secret using the following command:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic [your_k8s_secret_name] --from-file=[your_k8s_secret_key]=[pfx_certificate_file_fully_qualified_local_path]
|
||||
```
|
||||
|
||||
- `[pfx_certificate_file_fully_qualified_local_path]` is the path to the PFX file you obtained earlier
|
||||
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
|
||||
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
|
||||
|
||||
2. Create an `azurekeyvault.yaml` component file.
|
||||
|
||||
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the certificate stored in the Kubernetes secret store.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureCertificate
|
||||
secretKeyRef:
|
||||
name: "[your_k8s_secret_name]"
|
||||
key: "[your_k8s_secret_key]"
|
||||
auth:
|
||||
secretStore: kubernetes
|
||||
```
|
||||
|
||||
3. Apply the `azurekeyvault.yaml` component:
|
||||
|
||||
```bash
|
||||
kubectl apply -f azurekeyvault.yaml
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
## Using Managed Service Identities
|
||||
|
||||
Using MSI, authentication happens automatically by virtue of your application running on top of an Azure service that has an assigned identity. For example, when you create an Azure VM or an Azure Kubernetes Service cluster and choose to enable a managed identity for that, an Azure AD application is created for you and automatically assigned to the service. Your Dapr services can then leverage that identity to authenticate with Azure AD, transparently and without you having to specify any credential.
|
||||
|
||||
To get started with managed identities, first you need to assign an identity to a new or existing Azure resource. The instructions depend on the service use. Below are links to the official documentation:
|
||||
|
||||
- [Azure Kubernetes Service (AKS)](https://docs.microsoft.com/azure/aks/use-managed-identity)
|
||||
- [Azure App Service](https://docs.microsoft.com/azure/app-service/overview-managed-identity) (including Azure Web Apps and Azure Functions)
|
||||
- [Azure Virtual Machines (VM)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/qs-configure-cli-windows-vm)
|
||||
- [Azure Virtual Machines Scale Sets (VMSS)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/qs-configure-cli-windows-vmss)
|
||||
- [Azure Container Instance (ACI)](https://docs.microsoft.com/azure/container-instances/container-instances-managed-identity)
|
||||
|
||||
Other Azure application services may offer support for MSI; please check the documentation for those services to understand how to configure them.
|
||||
|
||||
After assigning a managed identity to your Azure resource, you will have credentials such as:
|
||||
|
||||
```json
|
||||
{
|
||||
"principalId": "<object-id>",
|
||||
"tenantId": "<tenant-id>",
|
||||
"type": "SystemAssigned",
|
||||
"userAssignedIdentities": null
|
||||
}
|
||||
```
|
||||
|
||||
From the list above, take note of **`principalId`** which is the ID of the Service Principal that was created. You'll need that to grant access to Azure resources to your Service Principal.
|
||||
|
||||
## Support for other Azure environments
|
||||
|
||||
By default, Dapr components are configured to interact with Azure resources in the "public cloud". If your application is deployed to another cloud, such as Azure China, Azure Government, or Azure Germany, you can enable that for supported components by setting the `azureEnvironment` metadata property to one of the supported values:
|
||||
|
||||
- Azure public cloud (default): `"AZUREPUBLICCLOUD"`
|
||||
- Azure China: `"AZURECHINACLOUD"`
|
||||
- Azure Government: `"AZUREUSGOVERNMENTCLOUD"`
|
||||
- Azure Germany: `"AZUREGERMANCLOUD"`
|
||||
|
||||
## References
|
||||
|
||||
- [Azure AD app credential: Azure CLI reference](https://docs.microsoft.com/cli/azure/ad/app/credential)
|
||||
- [Azure Managed Service Identity (MSI) overview](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview)
|
||||
- [Secrets building block]({{< ref secrets >}})
|
||||
- [How-To: Retrieve a secret]({{< ref "howto-secrets.md" >}})
|
||||
- [How-To: Reference secrets in Dapr components]({{< ref component-secrets.md >}})
|
||||
- [Secrets API reference]({{< ref secrets_api.md >}})
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
type: docs
|
||||
weight: 10000
|
||||
title: "Use the Dapr CLI in a GitHub Actions workflow"
|
||||
linkTitle: "GitHub Actions"
|
||||
description: "Learn how to add the Dapr CLI to your GitHub Actions to deploy and manage Dapr in your environments."
|
||||
---
|
||||
|
||||
Dapr can be integrated with GitHub Actions via the [Dapr tool installer](https://github.com/marketplace/actions/dapr-tool-installer) available in the GitHub Marketplace. This installer adds the Dapr CLI to your workflow, allowing you to deploy, manage, and upgrade Dapr across your environments.
|
||||
|
||||
## Overview
|
||||
|
||||
The `dapr/setup-dapr` action will install the specified version of the Dapr CLI on macOS, Linux and Windows runners. Once installed, you can run any [Dapr CLI command]({{< ref cli >}}) to manage your Dapr environments.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
- name: Install Dapr
|
||||
uses: dapr/setup-dapr@v1
|
||||
with:
|
||||
version: '{{% dapr-latest-version long="true" %}}'
|
||||
|
||||
- name: Initialize Dapr
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Get the credentials to K8s to use with dapr init
|
||||
az aks get-credentials --resource-group ${{ env.RG_NAME }} --name "${{ steps.azure-deployment.outputs.aksName }}"
|
||||
|
||||
# Initialize Dapr
|
||||
# Group the Dapr init logs so these lines can be collapsed.
|
||||
Write-Output "::group::Initialize Dapr"
|
||||
dapr init --kubernetes --wait --runtime-version ${{ env.DAPR_VERSION }}
|
||||
Write-Output "::endgroup::"
|
||||
|
||||
dapr status --kubernetes
|
||||
working-directory: ./twitter-sentiment-processor/demos/demo3
|
||||
```
|
|
@ -11,6 +11,7 @@ Welcome to the Dapr getting started guide!
|
|||
|
||||
{{% alert title="Dapr Concepts" color="primary" %}}
|
||||
If you are looking for an introductory overview of Dapr and learn more about basic Dapr terminology, it is recommended to visit the [concepts section]({{<ref concepts>}}).
|
||||
{{< button text="Learn more" page="concepts" >}}
|
||||
{{% /alert %}}
|
||||
|
||||
This guide will walk you through a series of steps to install, initialize and start using Dapr. The recommended way to get started with Dapr is to setup a local development environment (also referred to as [_self-hosted_ mode]({{< ref self-hosted >}})) which includes the Dapr CLI, Dapr sidecar binaries, and some default components that can help you start using Dapr quickly.
|
||||
|
@ -23,3 +24,4 @@ The following steps in this guide are:
|
|||
1. Explore Dapr quickstarts
|
||||
|
||||
{{< button text="First step: Install the Dapr CLI >>" page="install-dapr-cli" >}}
|
||||
<br><br>
|
|
@ -52,8 +52,8 @@ dapr --version
|
|||
|
||||
Output should look like this:
|
||||
```
|
||||
CLI version: 1.3.0
|
||||
Runtime version: 1.3.0
|
||||
CLI version: {{% dapr-latest-version cli="true" %}}
|
||||
Runtime version: {{% dapr-latest-version long="true" %}}
|
||||
```
|
||||
|
||||
### Step 4: Verify containers are running
|
||||
|
|
|
@ -17,11 +17,12 @@ The [Dapr Quickstarts](https://github.com/dapr/quickstarts/tree/v1.0.0) are a co
|
|||
|
||||
| Quickstart | Description |
|
||||
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [Hello World](https://github.com/dapr/quickstarts/tree/v1.3.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. |
|
||||
| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.3.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. |
|
||||
| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.3.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. |
|
||||
| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.3.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. |
|
||||
| [Bindings](https://github.com/dapr/quickstarts/tree/v1.3.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. |
|
||||
| [Middleware](https://github.com/dapr/quickstarts/tree/v1.3.0/middleware) | Demonstrates use of Dapr middleware to enable OAuth 2.0 authorization. |
|
||||
| [Observability](https://github.com/dapr/quickstarts/tree/v1.3.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. |
|
||||
| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.3.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. |
|
||||
| [Hello World](https://github.com/dapr/quickstarts/tree/v1.4.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. |
|
||||
| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.4.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. |
|
||||
| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.4.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. |
|
||||
| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.4.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. |
|
||||
| [Bindings](https://github.com/dapr/quickstarts/tree/v1.4.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. |
|
||||
| [Middleware](https://github.com/dapr/quickstarts/tree/v1.4.0/middleware) | Demonstrates use of Dapr middleware to enable OAuth 2.0 authorization. |
|
||||
| [Observability](https://github.com/dapr/quickstarts/tree/v1.4.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. |
|
||||
| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.4.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. |
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ Go to [this]({{< ref "howto-secrets.md" >}}) link to see all the secret stores s
|
|||
|
||||
## Referencing secrets
|
||||
|
||||
While you have the option to use plain text secrets, this is not recommended for production:
|
||||
While you have the option to use plain text secrets (like MyPassword), as shown in the yaml below for the `value` of `redisPassword`, this is not recommended for production:
|
||||
|
||||
```yml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
|
@ -38,7 +38,9 @@ spec:
|
|||
value: MyPassword
|
||||
```
|
||||
|
||||
Instead create the secret in your secret store and reference it in the component definition:
|
||||
Instead create the secret in your secret store and reference it in the component definition. There are two cases for this shown below -- the "Secret contains an embedded key" and the "Secret is a string".
|
||||
|
||||
The "Secret contains an embedded key" case applies when there is a key embedded within the secret, i.e. the secret is **not** an entire connection string. This is shown in the following component definition yaml.
|
||||
|
||||
```yml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
|
@ -62,7 +64,30 @@ auth:
|
|||
|
||||
`SECRET_STORE_NAME` is the name of the configured [secret store component]({{< ref supported-secret-stores >}}). When running in Kubernetes and using a Kubernetes secret store, the field `auth.SecretStore` defaults to `kubernetes` and can be left empty.
|
||||
|
||||
The above component definition tells Dapr to extract a secret named `redis-secret` from the defined secret store and assign the value of the `redis-password` key in the secret to the `redisPassword` field in the Component.
|
||||
The above component definition tells Dapr to extract a secret named `redis-secret` from the defined `secretStore` and assign the value associated with the `redis-password` key embedded in the secret to the `redisPassword` field in the component. One use of this case is when your code is constructing a connection string, for example putting together a URL, a secret, plus other information as necessary, into a string.
|
||||
|
||||
On the other hand, the below "Secret is a string" case applies when there is NOT a key embedded in the secret. Rather, the secret is just a string. Therefore, in the `secretKeyRef` section both the secret `name` and the secret `key` will be identical. This is the case when the secret itself is an entire connection string with no embedded key whose value needs to be extracted. Typically a connection string consists of connection information, some sort of secret to allow connection, plus perhaps other information and does not require a separate "secret". This case is shown in the below component definition yaml.
|
||||
|
||||
```yml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: servicec-inputq-azkvsecret-asbqueue
|
||||
spec:
|
||||
type: bindings.azure.servicebusqueues
|
||||
version: v1
|
||||
metadata:
|
||||
-name: connectionString
|
||||
secretKeyRef:
|
||||
name: asbNsConnString
|
||||
key: asbNsConnString
|
||||
-name: queueName
|
||||
value: servicec-inputq
|
||||
auth:
|
||||
secretStore: <SECRET_STORE_NAME>
|
||||
|
||||
```
|
||||
The above "Secret is a string" case yaml tells Dapr to extract a connection string named `asbNsConnstring` from the defined `secretStore` and assign the value to the `connectionString` field in the component since there is no key embedded in the "secret" from the `secretStore` because it is a plain string. This requires the secret `name` and secret `key` to be identical.
|
||||
|
||||
## Example
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ description: "Control how many requests and events will invoke your application
|
|||
A common scenario in distributed computing is to only allow for a given number of requests to execute concurrently.
|
||||
Using Dapr, you can control how many requests and events will invoke your application simultaneously.
|
||||
|
||||
*Note that this rate limiing is guaranteed for every event that's coming from Dapr, meaning Pub/Sub events, direct invocation from other services, bindings events etc. Dapr can't enforce the concurrency policy on requests that are coming to your app externally.*
|
||||
*Note that this rate limiting is guaranteed for every event that's coming from Dapr, meaning Pub/Sub events, direct invocation from other services, bindings events etc. Dapr can't enforce the concurrency policy on requests that are coming to your app externally.*
|
||||
|
||||
*Note that rate limiting per second can be achieved by using the **middleware.http.ratelimit** middleware. However, there is an imporant difference between the two approaches. The rate limit middlware is time bound and limits the number of requests per second, while the `app-max-concurrency` flag specifies the number of concurrent requests (and events) at any point of time. See [Rate limit middleware]({{< ref middleware-rate-limit.md >}}). *
|
||||
|
||||
|
@ -61,4 +61,4 @@ To set app-max-concurrency with the Dapr CLI for running on your local dev machi
|
|||
dapr run --app-max-concurrency 1 --app-port 5000 python ./app.py
|
||||
```
|
||||
|
||||
The above examples will effectively turn your app into a single concurrent service.
|
||||
The above examples will effectively turn your app into a single concurrent service.
|
||||
|
|
|
@ -10,12 +10,6 @@ Access control enables the configuration of policies that restrict what operatio
|
|||
|
||||
An access control policy is specified in configuration and be applied to Dapr sidecar for the *called* application. Example access policies are shown below and access to the called app is based on the matched policy action. You can provide a default global action for all calling applications and if no access control policy is specified, the default behavior is to allow all calling applications to access to the called app.
|
||||
|
||||
Watch this [video](https://youtu.be/j99RN_nxExA?t=1108) on how to apply access control list for service invocation.
|
||||
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="688" height="430" src="https://www.youtube.com/embed/j99RN_nxExA?start=1108" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
## Concepts
|
||||
|
||||
**TrustDomain** - A "trust domain" is a logical group to manage trust relationships. Every application is assigned a trust domain which can be specified in the access control list policy spec. If no policy spec is defined or an empty trust domain is specified, then a default value "public" is used. This trust domain is used to generate the identity of the application in the TLS cert.
|
||||
|
@ -357,3 +351,10 @@ spec:
|
|||
- name: python
|
||||
image: dapriosamples/hello-k8s-python:edge
|
||||
```
|
||||
|
||||
## Community call demo
|
||||
Watch this [video](https://youtu.be/j99RN_nxExA?t=1108) on how to apply access control list for service invocation.
|
||||
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="688" height="430" src="https://www.youtube.com/embed/j99RN_nxExA?start=1108" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
|
@ -12,7 +12,7 @@ description: >
|
|||
## Prerequisites
|
||||
|
||||
- [Docker](https://docs.docker.com/install/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
|
||||
|
||||
## Deploy an Azure Kubernetes Service cluster
|
||||
|
|
|
@ -8,7 +8,7 @@ description: "Setup a Google Kubernetes Engine cluster"
|
|||
|
||||
### Prerequisites
|
||||
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- [Google Cloud SDK](https://cloud.google.com/sdk)
|
||||
|
||||
## Create a new cluster
|
||||
|
|
|
@ -12,7 +12,7 @@ description: >
|
|||
## Prerequisites
|
||||
|
||||
- [Docker](https://docs.docker.com/install/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- [Minikube](https://minikube.sigs.k8s.io/docs/start/)
|
||||
|
||||
> Note: For Windows, enable Virtualization in BIOS and [install Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)
|
||||
|
|
|
@ -15,7 +15,7 @@ For more information on what is deployed to your Kubernetes cluster read the [Ku
|
|||
## Prerequisites
|
||||
|
||||
- Install [Dapr CLI]({{< ref install-dapr-cli.md >}})
|
||||
- Install [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- Install [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- Kubernetes cluster (see below if needed)
|
||||
|
||||
### Create cluster
|
||||
|
@ -122,7 +122,7 @@ The latest Dapr helm chart no longer supports Helm v2. Please migrate from Helm
|
|||
|
||||
```bash
|
||||
helm upgrade --install dapr dapr/dapr \
|
||||
--version=1.2 \
|
||||
--version={{% dapr-latest-version short="true" %}} \
|
||||
--namespace dapr-system \
|
||||
--create-namespace \
|
||||
--wait
|
||||
|
@ -132,7 +132,7 @@ The latest Dapr helm chart no longer supports Helm v2. Please migrate from Helm
|
|||
|
||||
```bash
|
||||
helm upgrade --install dapr dapr/dapr \
|
||||
--version=1.2 \
|
||||
--version={{% dapr-latest-version short="true" %}} \
|
||||
--namespace dapr-system \
|
||||
--create-namespace \
|
||||
--set global.ha.enabled=true \
|
||||
|
|
|
@ -11,15 +11,15 @@ description: "Follow these steps to upgrade Dapr on Kubernetes and ensure a smoo
|
|||
- [Dapr CLI]({{< ref install-dapr-cli.md >}})
|
||||
- [Helm 3](https://github.com/helm/helm/releases) (if using Helm)
|
||||
|
||||
## Upgrade existing cluster to 1.3.0
|
||||
## Upgrade existing cluster to {{% dapr-latest-version long="true" %}}
|
||||
There are two ways to upgrade the Dapr control plane on a Kubernetes cluster using either the Dapr CLI or Helm.
|
||||
|
||||
### Dapr CLI
|
||||
|
||||
The example below shows how to upgrade to version 1.3.0:
|
||||
The example below shows how to upgrade to version {{% dapr-latest-version long="true" %}}:
|
||||
|
||||
```bash
|
||||
dapr upgrade -k --runtime-version=1.3.0
|
||||
dapr upgrade -k --runtime-version={{% dapr-latest-version long="true" %}}
|
||||
```
|
||||
|
||||
You can provide all the available Helm chart configurations using the Dapr CLI.
|
||||
|
@ -43,7 +43,7 @@ To resolve this issue please run the follow command to upgrade the CustomResourc
|
|||
kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/5a15b3e0f093d2d0938b12f144c7047474a290fe/charts/dapr/crds/configuration.yaml
|
||||
```
|
||||
|
||||
Then proceed with the `dapr upgrade --runtime-version 1.3.0 -k` command as above.
|
||||
Then proceed with the `dapr upgrade --runtime-version {{% dapr-latest-version long="true" %}} -k` command as above.
|
||||
|
||||
### Helm
|
||||
|
||||
|
|
|
@ -25,11 +25,11 @@ description: "Follow these steps to upgrade Dapr in self-hosted mode and ensure
|
|||
dapr init
|
||||
```
|
||||
|
||||
1. Ensure you are using the latest version of Dapr (v1.3) with:
|
||||
1. Ensure you are using the latest version of Dapr (v{{% dapr-latest-version long="true" %}})) with:
|
||||
|
||||
```bash
|
||||
$ dapr --version
|
||||
|
||||
CLI version: 1.3
|
||||
Runtime version: 1.3
|
||||
CLI version: {{% dapr-latest-version short="true" %}}
|
||||
Runtime version: {{% dapr-latest-version short="true" %}}
|
||||
```
|
||||
|
|
|
@ -9,7 +9,7 @@ description: "How to install Fluentd, Elastic Search, and Kibana to search logs
|
|||
## Prerequisites
|
||||
|
||||
- Kubernetes (> 1.14)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- [Helm 3](https://helm.sh/)
|
||||
|
||||
## Install Elastic search and Kibana
|
||||
|
|
|
@ -10,7 +10,7 @@ description: "Enable Dapr metrics and logs with Azure Monitor for Azure Kubernet
|
|||
|
||||
- [Azure Kubernetes Service](https://docs.microsoft.com/en-us/azure/aks/)
|
||||
- [Enable Azure Monitor For containers in AKS](https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-overview)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- [Helm 3](https://helm.sh/)
|
||||
|
||||
## Enable Prometheus metric scrape using config map
|
||||
|
|
|
@ -67,7 +67,7 @@ Once Prometheus is running, you'll be able to visit its dashboard by visiting `h
|
|||
### Prerequisites
|
||||
|
||||
- Kubernetes (> 1.14)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- [Helm 3](https://helm.sh/)
|
||||
|
||||
### Install Prometheus
|
||||
|
|
|
@ -9,8 +9,10 @@ Preview features in Dapr are considered experimental when they are first release
|
|||
|
||||
|
||||
## Current preview features
|
||||
| Description | Setting | Documentation |
|
||||
|-------------|---------|---------------|
|
||||
| Preview feature that enables Actors to be called multiple times in the same call chain allowing call backs between actors. | Actor.Reentrancy | [Actor reentrancy]({{<ref actor-reentrancy>}}) |
|
||||
| Preview feature that allows Actor reminders to be partitioned across multiple keys in the underlying statestore in order to improve scale and performance. | Actor.TypeMetadata | [How-To: Partition Actor Reminders]({{< ref "howto-actors.md#partitioning-reminders" >}}) |
|
||||
| Preview feature that enables you to call endpoints using service invocation on gRPC services through Dapr via gRPC proxying, without requiring the use of Dapr SDKs. | proxy.grpc | [How-To: Invoke services using gRPC]({{<ref howto-invoke-services-grpc>}}) |
|
||||
| Feature | Description | Setting | Documentation |
|
||||
| ---------- |-------------|---------|---------------|
|
||||
| **Actor reentrancy** | Enables actors to be called multiple times in the same call chain allowing call backs between actors. | `Actor.Reentrancy` | [Actor reentrancy]({{<ref actor-reentrancy>}}) |
|
||||
| **Partition actor reminders** | Allows actor reminders to be partitioned across multiple keys in the underlying statestore in order to improve scale and performance. | `Actor.TypeMetadata` | [How-To: Partition Actor Reminders]({{< ref "howto-actors.md#partitioning-reminders" >}}) |
|
||||
| **gRPC proxying** | Enables calling endpoints using service invocation on gRPC services through Dapr via gRPC proxying, without requiring the use of Dapr SDKs. | `proxy.grpc` | [How-To: Invoke services using gRPC]({{<ref howto-invoke-services-grpc>}}) |
|
||||
| **State store encryption** | Enables automatic client side encryption for state stores | `State.Encryption` | [How-To: Encrypt application state]({{<ref howto-encrypt-state>}}) |
|
||||
| **Pub/Sub routing** | Allow the use of expressions to route cloud events to different URIs/paths and event handlers in your application. | `PubSub.Routing` | [How-To: Publish a message and subscribe to a topic]({{<ref howto-route-messages>}}) |
|
||||
|
|
|
@ -31,15 +31,20 @@ The table below shows the versions of Dapr releases that have been tested togeth
|
|||
|
||||
| Release date | Runtime | CLI | SDKs | Dashboard | Status |
|
||||
|--------------------|:--------:|:--------|---------|---------|---------|
|
||||
| Feb 17th 2021 | 1.0.0</br>| 1.0.0 | Java 1.0.0 </br>Go 1.0.0 </br>PHP 1.0.0 </br>Python 1.0.0 </br>.NET 1.0.0 | 0.6.0 | Unsupported |
|
||||
| Mar 4th 2021 | 1.0.1</br>| 1.0.1 | Java 1.0.2 </br>Go 1.0.0 </br>PHP 1.0.0 </br>Python 1.0.0 </br>.NET 1.0.0 | 0.6.0 | Unsupported |
|
||||
| Apr 1st 2021 | 1.1.0</br> | 1.1.0 | Java 1.0.2 </br>Go 1.1.0 </br>PHP 1.0.0 </br>Python 1.1.0 </br>.NET 1.1.0 | 0.6.0 | Unsupported |
|
||||
| Apr 6th 2021 | 1.1.1</br> | 1.1.0 | Java 1.0.2 </br>Go 1.1.0 </br>PHP 1.0.0 </br>Python 1.1.0 </br>.NET 1.1.0 | 0.6.0 | Unsupported |
|
||||
| Apr 16th 2021 | 1.1.2</br> | 1.1.0 | Java 1.0.2 </br>Go 1.1.0 </br>PHP 1.0.0 </br>Python 1.1.0 </br>.NET 1.1.0 | 0.6.0 | Unsupported |
|
||||
| May 26th 2021 | 1.2.0</br> | 1.2.0 | Java 1.1.0 </br>Go 1.1.0 </br>PHP 1.1.0 </br>Python 1.1.0 </br>.NET 1.2.0 | 0.6.0 | Supported |
|
||||
| June 16th 2021 | 1.2.1</br> | 1.2.0 | Java 1.1.0 </br>Go 1.1.0 </br>PHP 1.1.0 </br>Python 1.1.0 </br>.NET 1.2.0 | 0.6.0 | Supported |
|
||||
| June 16th 2021 | 1.2.2</br> | 1.2.0 | Java 1.1.0 </br>Go 1.1.0 </br>PHP 1.1.0 </br>Python 1.1.0 </br>.NET 1.2.0 | 0.6.0 | Supported |
|
||||
| July 26th 2021 | 1.3</br> | 1.3.0 | Java 1.2.0 </br>Go 1.2.0 </br>PHP 1.1.0 </br>Python 1.2.0 </br>.NET 1.3.0 | 0.7.0 | Supported (current) |
|
||||
| Feb 17th 2021 | 1.0.0</br> | 1.0.0 | Java 1.0.0 </br>Go 1.0.0 </br>PHP 1.0.0 </br>Python 1.0.0 </br>.NET 1.0.0 | 0.6.0 | Unsupported |
|
||||
| Mar 4th 2021 | 1.0.1</br> | 1.0.1 | Java 1.0.2 </br>Go 1.0.0 </br>PHP 1.0.0 </br>Python 1.0.0 </br>.NET 1.0.0 | 0.6.0 | Unsupported |
|
||||
| Apr 1st 2021 | 1.1.0</br> | 1.1.0 | Java 1.0.2 </br>Go 1.1.0 </br>PHP 1.0.0 </br>Python 1.1.0 </br>.NET 1.1.0 | 0.6.0 | Unsupported |
|
||||
| Apr 6th 2021 | 1.1.1</br> | 1.1.0 | Java 1.0.2 </br>Go 1.1.0 </br>PHP 1.0.0 </br>Python 1.1.0 </br>.NET 1.1.0 | 0.6.0 | Unsupported |
|
||||
| Apr 16th 2021 | 1.1.2</br> | 1.1.0 | Java 1.0.2 </br>Go 1.1.0 </br>PHP 1.0.0 </br>Python 1.1.0 </br>.NET 1.1.0 | 0.6.0 | Unsupported |
|
||||
| May 26th 2021 | 1.2.0</br> | 1.2.0 | Java 1.1.0 </br>Go 1.1.0 </br>PHP 1.1.0 </br>Python 1.1.0 </br>.NET 1.2.0 | 0.6.0 | Unsupported |
|
||||
| Jun 16th 2021 | 1.2.1</br> | 1.2.0 | Java 1.1.0 </br>Go 1.1.0 </br>PHP 1.1.0 </br>Python 1.1.0 </br>.NET 1.2.0 | 0.6.0 | Unsupported |
|
||||
| Jun 16th 2021 | 1.2.2</br> | 1.2.0 | Java 1.1.0 </br>Go 1.1.0 </br>PHP 1.1.0 </br>Python 1.1.0 </br>.NET 1.2.0 | 0.6.0 | Unsupported |
|
||||
| Jul 26th 2021 | 1.3</br> | 1.3.0 | Java 1.2.0 </br>Go 1.2.0 </br>PHP 1.1.0 </br>Python 1.2.0 </br>.NET 1.3.0 | 0.7.0 | Supported |
|
||||
| Sep 14th 2021 | 1.3.1</br> | 1.3.0 | Java 1.2.0 </br>Go 1.2.0 </br>PHP 1.1.0 </br>Python 1.2.0 </br>.NET 1.3.0 | 0.7.0 | Supported |
|
||||
| Sep 15th 2021 | 1.4</br> | 1.4.0 | Java 1.3.0 </br>Go 1.3.0 </br>PHP 1.2.0 </br>Python 1.3.0 </br>.NET 1.4.0 | 0.8.0 | Supported |
|
||||
| Sep 22nd 2021 | 1.4.1</br> | 1.4.0 | Java 1.3.0 </br>Go 1.3.0 </br>PHP 1.2.0 </br>Python 1.3.0 </br>.NET 1.4.0 | 0.8.0 | Supported
|
||||
| Sep 24th 2021 | 1.4.2</br> | 1.4.0 | Java 1.3.0 </br>Go 1.3.0 </br>PHP 1.2.0 </br>Python 1.3.0 </br>.NET 1.4.0 | 0.8.0 | Supported |
|
||||
| Oct 7th 2021 | 1.4.3</br> | 1.4.0 | Java 1.3.0 </br>Go 1.3.0 </br>PHP 1.2.0 </br>Python 1.3.0 </br>.NET 1.4.0 | 0.8.0 | Supported (current) |
|
||||
|
||||
## Upgrade paths
|
||||
After the 1.0 release of the runtime there may be situations where it is necessary to explicitly upgrade through an additional release to reach the desired target. For example an upgrade from v1.0 to v1.2 may need go pass through v1.1
|
||||
|
@ -52,10 +57,17 @@ General guidance on upgrading can be found for [self hosted mode]({{<ref self-ho
|
|||
|--------------------------|-----------------------|------------------------- |
|
||||
| 1.0.0 or 1.0.1 | N/A | 1.1.2 |
|
||||
| | 1.1.2 | 1.2.2 |
|
||||
| | 1.2.2 | 1.3.0 |
|
||||
| | 1.2.2 | 1.3.1 |
|
||||
| | 1.3.1 | 1.4.3 |
|
||||
| 1.1.0 to 1.1.2 | N/A | 1.2.2 |
|
||||
| | 1.2.2 | 1.3.0 |
|
||||
| 1.2.0 to 1.2.2 | N/A | 1.3.0 |
|
||||
| | 1.2.2 | 1.3.1 |
|
||||
| | 1.3.1 | 1.4.3 |
|
||||
| 1.2.0 to 1.2.2 | N/A | 1.3.1 |
|
||||
| | 1.3.1 | 1.4.3 |
|
||||
| 1.3.0 | N/A | 1.3.1 |
|
||||
| | 1.3.1 | 1.4.3 |
|
||||
| 1.3.1 | N/A | 1.4.3 |
|
||||
| 1.4.0 to 1.4.2 | N/A | 1.4.3 |
|
||||
|
||||
## Feature and deprecations
|
||||
There is a process for announcing feature deprecations. Deprecations are applied two (2) releases after the release in which they were announced. For example Feature X is announced to be deprecated in the 1.0.0 release notes and will then be removed in 1.2.0.
|
||||
|
|
|
@ -95,14 +95,14 @@ Code | Description
|
|||
### Examples
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret \
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret
|
||||
```
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret?metadata.version_id=15&metadata.version_stage=AAA \
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret?metadata.version_id=15&metadata.version_stage=AAA
|
||||
```
|
||||
|
||||
> Note, in case of deploying into namespace other than default`, the above query will also have to include the namespace metadata (e.g. `production` below)
|
||||
> Note, in case of deploying into namespace other than default, the above query will also have to include the namespace metadata (e.g. `production` below)
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret?metadata.version_id=15&?metadata.namespace=production
|
||||
|
@ -165,7 +165,7 @@ Code | Description
|
|||
### Examples
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/bulk \
|
||||
curl http://localhost:3500/v1.0/secrets/vault/bulk
|
||||
```
|
||||
|
||||
```json
|
||||
|
|
|
@ -39,6 +39,7 @@ This table is meant to help users understand the equivalent options for running
|
|||
| `--version` | `--version` | `-v` | not supported | Prints the runtime version |
|
||||
| not supported | not supported | | `dapr.io/enabled` | Setting this paramater to true injects the Dapr sidecar into the pod |
|
||||
| not supported | not supported | | `dapr.io/api-token-secret` | Tells Dapr which Kubernetes secret to use for token based API authentication. By default this is not set |
|
||||
| `--dapr-listen-addresses` | not supported | | `dapr.io/sidecar-listen-addresses` | Comma separated list of IP addresses that sidecar will listen to. Defaults to all in standalone mode. Defaults to `[::1],127.0.0.1` in Kubernetes. To listen to all IPv4 addresses, use `0.0.0.0`. To listen to all IPv6 addresses, use `[::]`.
|
||||
| not supported | not supported | | `dapr.io/sidecar-cpu-limit` | Maximum amount of CPU that the Dapr sidecar can use. See valid values [here](https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/). By default this is not set
|
||||
| not supported | not supported | | `dapr.io/sidecar-memory-limit` | Maximum amount of Memory that the Dapr sidecar can use. See valid values [here](https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/). By default this is not set
|
||||
| not supported | not supported | | `dapr.io/sidecar-cpu-request` | Amount of CPU that the Dapr sidecar requests. See valid values [here](https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/). By default this is not set
|
||||
|
|
|
@ -23,6 +23,7 @@ dapr dashboard [flags]
|
|||
|
||||
| Name | Environment Variable | Default | Description |
|
||||
|------|----------------------|---------|-------------|
|
||||
| `--address`, `-a` | | `localhost` | Address to listen on. Only accepts IP address or localhost as a value |
|
||||
| `--help`, `-h` | | | Prints this help message |
|
||||
| `--kubernetes`, `-k` | | `false` | Opens Dapr dashboard in local browser via local proxy to Kubernetes cluster |
|
||||
| `--namespace`, `-n` | | `dapr-system` | The namespace where Dapr dashboard is running |
|
||||
|
@ -46,6 +47,11 @@ dapr dashboard -p 9999
|
|||
dapr dashboard -k
|
||||
```
|
||||
|
||||
### Port forward to dashboard service running in Kubernetes on all addresses on a specified port
|
||||
```bash
|
||||
dapr dashboard -k -p 9999 --address 0.0.0.0
|
||||
```
|
||||
|
||||
### Port forward to dashboard service running in Kubernetes on a specified port
|
||||
```bash
|
||||
dapr dashboard -k -p 9999
|
||||
|
|
|
@ -50,6 +50,7 @@ Table captions:
|
|||
|------|:----------------:|:-----------------:|--------| ------ |----------|
|
||||
| [Alibaba Cloud DingTalk]({{< ref alicloud-dingtalk.md >}}) | ✅ | ✅ | Alpha | v1 | 1.2 |
|
||||
| [Alibaba Cloud OSS]({{< ref alicloudoss.md >}}) | | ✅ | Alpha | v1 | 1.0 |
|
||||
| [Alibaba Cloud Tablestore]({{< ref alicloudtablestore.md >}}) | | ✅ | Alpha | v1 | 1.4 |
|
||||
|
||||
### Amazon Web Services (AWS)
|
||||
|
||||
|
@ -57,6 +58,7 @@ Table captions:
|
|||
|------|:----------------:|:-----------------:|--------| ------ |----------|
|
||||
| [AWS DynamoDB]({{< ref dynamodb.md >}}) | | ✅ | Alpha | v1 | 1.0 |
|
||||
| [AWS S3]({{< ref s3.md >}}) | | ✅ | Alpha | v1 | 1.0 |
|
||||
| [AWS SES]({{< ref ses.md >}}) | | ✅ | Alpha | v1 | 1.4 |
|
||||
| [AWS SNS]({{< ref sns.md >}}) | | ✅ | Alpha | v1 | 1.0 |
|
||||
| [AWS SQS]({{< ref sqs.md >}}) | ✅ | ✅ | Alpha | v1 | 1.0 |
|
||||
| [AWS Kinesis]({{< ref kinesis.md >}}) | ✅ | ✅ | Alpha | v1 | 1.0 |
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
---
|
||||
type: docs
|
||||
title: "Alibaba Cloud Tablestore binding spec"
|
||||
linkTitle: "Alibaba Cloud Tablestore"
|
||||
description: "Detailed documentation on the Alibaba Tablestore binding component"
|
||||
aliases:
|
||||
- "/operations/components/setup-bindings/supported-bindings/alicloudtablestore/"
|
||||
---
|
||||
|
||||
## Component format
|
||||
|
||||
To setup an Alibaba Cloud Tablestore binding create a component of type `bindings.alicloud.tablestore`. See [this guide]({{< ref "howto-bindings.md#1-create-a-binding" >}}) on how to create and apply a secretstore configuration. See this guide on [referencing secrets]({{< ref component-secrets.md >}}) to retrieve and use the secret with Dapr components.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: mytablestore
|
||||
namespace: default
|
||||
spec:
|
||||
type: bindings.alicloud.tablestore
|
||||
version: v1
|
||||
metadata:
|
||||
- name: endpoint
|
||||
value: "[endpoint]"
|
||||
- name: accessKeyID
|
||||
value: "[key-id]"
|
||||
- name: accessKey
|
||||
value: "[access-key]"
|
||||
- name: instanceName
|
||||
value: "[instance]"
|
||||
- name: tableName
|
||||
value: "[table]"
|
||||
- name: endpoint
|
||||
value: "[endpoint]"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Binding support | Details | Example |
|
||||
|---------------|----------|---------|---------|---------|
|
||||
| `endpoint` | Y | Output | Alicloud Tablestore endpoint. | https://tablestore-cn-hangzhou.aliyuncs.com
|
||||
| `accessKeyID` | Y | Output | Access key ID credential. |
|
||||
| `accessKey` | Y | Output | Access key credential. |
|
||||
| `instanceName` | Y | Output | Name of the instance. |
|
||||
| `tableName` | Y | Output | Name of the table. |
|
||||
|
||||
## Binding support
|
||||
|
||||
This component supports **output binding** with the following operations:
|
||||
- `create`: [Create object](#create-object)
|
||||
|
||||
|
||||
### Create object
|
||||
|
||||
To perform a create object operation, invoke the binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "create",
|
||||
"data": "YOUR_CONTENT",
|
||||
"metadata": {
|
||||
"primaryKeys": "pk1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{% alert title="Note" color="primary" %}}
|
||||
Note the `metadata.primaryKeys` field is mandatory.
|
||||
{{% /alert %}}
|
||||
|
||||
### Delete object
|
||||
|
||||
To perform a delete object operation, invoke the binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "delete",
|
||||
"metadata": {
|
||||
"primaryKeys": "pk1",
|
||||
"columnToGet": "name,age,date"
|
||||
},
|
||||
"data": {
|
||||
"pk1": "data1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{% alert title="Note" color="primary" %}}
|
||||
Note the `metadata.primaryKeys` field is mandatory.
|
||||
{{% /alert %}}
|
||||
|
||||
### List objects
|
||||
|
||||
To perform a list objects operation, invoke the binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "delete",
|
||||
"metadata": {
|
||||
"primaryKeys": "pk1",
|
||||
"columnToGet": "name,age,date"
|
||||
},
|
||||
"data": {
|
||||
"pk1": "data1",
|
||||
"pk2": "data2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{% alert title="Note" color="primary" %}}
|
||||
Note the `metadata.primaryKeys` field is mandatory.
|
||||
{{% /alert %}}
|
||||
|
||||
### Get object
|
||||
|
||||
To perform a get object operation, invoke the binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "delete",
|
||||
"metadata": {
|
||||
"primaryKeys": "pk1"
|
||||
},
|
||||
"data": {
|
||||
"pk1": "data1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{% alert title="Note" color="primary" %}}
|
||||
Note the `metadata.primaryKeys` field is mandatory.
|
||||
{{% /alert %}}
|
||||
|
||||
## Related links
|
||||
|
||||
- [Bindings building block]({{< ref bindings >}})
|
||||
- [How-To: Use bindings to interface with external resources]({{< ref howto-bindings.md >}})
|
||||
- [Bindings API reference]({{< ref bindings_api.md >}})
|
|
@ -44,6 +44,10 @@ spec:
|
|||
value: https://www.googleapis.com/robot/v1/metadata/x509/<project-name>.iam.gserviceaccount.com
|
||||
- name: private_key
|
||||
value: PRIVATE KEY
|
||||
- name: decodeBase64
|
||||
value: <bool>
|
||||
- name: encodeBase64
|
||||
value: <bool>
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
|
@ -65,12 +69,17 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| token_uri | Y | Output | Google account token uri | `https://oauth2.googleapis.com/token`
|
||||
| auth_provider_x509_cert_url | Y | Output | GCP credentials cert url | `https://www.googleapis.com/oauth2/v1/certs`
|
||||
| client_x509_cert_url | Y | Output | GCP credentials project x509 cert url | `https://www.googleapis.com/robot/v1/metadata/x509/<PROJECT_NAME>.iam.gserviceaccount.com`
|
||||
| decodeBase64 | N | Output | Configuration to decode base64 file content before saving to bucket storage. (In case of saving a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
| encodeBase64 | N | Output | Configuration to encode base64 file content before return the content. (In case of opening a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
|
||||
## Binding support
|
||||
|
||||
This component supports **output binding** with the following operations:
|
||||
|
||||
- `create`
|
||||
- `create` : [Create file](#create-file)
|
||||
- `get` : [Get file](#get-file)
|
||||
- `delete` : [Delete file](#delete-file)
|
||||
- `list`: [List file](#list-files)
|
||||
|
||||
### Create file
|
||||
|
||||
|
@ -84,10 +93,11 @@ To perform a create operation, invoke the GCP Storage Bucket binding with a `POS
|
|||
"data": "YOUR_CONTENT"
|
||||
}
|
||||
```
|
||||
The metadata parameters are:
|
||||
- `key` - (optional) the name of the object
|
||||
- `decodeBase64` - (optional) configuration to decode base64 file content before saving to storage
|
||||
|
||||
#### Examples
|
||||
|
||||
|
||||
##### Save text to a random generated UUID file
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
@ -113,14 +123,14 @@ To perform a create operation, invoke the GCP Storage Bucket binding with a `POS
|
|||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"Hello World\", \"metadata\": { \"name\": \"my-test-file.txt\" } }" \
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"Hello World\", \"metadata\": { \"key\": \"my-test-file.txt\" } }" \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "create", "data": "Hello World", "metadata": { "name": "my-test-file.txt" } }' \
|
||||
curl -d '{ "operation": "create", "data": "Hello World", "metadata": { "key": "my-test-file.txt" } }' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
@ -138,19 +148,175 @@ Then you can upload it as you would normally:
|
|||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"(YOUR_FILE_CONTENTS)\", \"metadata\": { \"name\": \"my-test-file.jpg\" } }" http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"(YOUR_FILE_CONTENTS)\", \"metadata\": { \"key\": \"my-test-file.jpg\" } }" http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "create", "data": "$(cat my-test-file.jpg)", "metadata": { "name": "my-test-file.jpg" } }' \
|
||||
curl -d '{ "operation": "create", "data": "$(cat my-test-file.jpg)", "metadata": { "key": "my-test-file.jpg" } }' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
#### Response
|
||||
|
||||
The response body will contain the following JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"objectURL":"https://storage.googleapis.com/<your bucket>/<key>",
|
||||
}
|
||||
```
|
||||
|
||||
### Get object
|
||||
|
||||
To perform a get file operation, invoke the GCP bucket binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "get",
|
||||
"metadata": {
|
||||
"key": "my-test-file.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The metadata parameters are:
|
||||
|
||||
- `key` - the name of the object
|
||||
- `encodeBase64` - (optional) configuration to encode base64 file content before return the content.
|
||||
|
||||
|
||||
#### Example
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ \"operation\": \"get\", \"metadata\": { \"key\": \"my-test-file.txt\" }}' http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "get", "metadata": { "key": "my-test-file.txt" }}' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
#### Response
|
||||
|
||||
The response body contains the value stored in the object.
|
||||
|
||||
|
||||
### Delete object
|
||||
|
||||
To perform a delete object operation, invoke the GCP bucket binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "delete",
|
||||
"metadata": {
|
||||
"key": "my-test-file.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The metadata parameters are:
|
||||
|
||||
- `key` - the name of the object
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
##### Delete object
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ \"operation\": \"delete\", \"metadata\": { \"key\": \"my-test-file.txt\" }}' http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "delete", "metadata": { "key": "my-test-file.txt" }}' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
#### Response
|
||||
An HTTP 204 (No Content) and empty body will be retuned if successful.
|
||||
|
||||
|
||||
### List objects
|
||||
|
||||
To perform a list object operation, invoke the S3 binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "list",
|
||||
"data": {
|
||||
"maxResults": 10,
|
||||
"prefix": "file",
|
||||
"delimiter": "i0FvxAn2EOEL6"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The data parameters are:
|
||||
|
||||
- `maxResults` - (optional) sets the maximum number of keys returned in the response. By default the action returns up to 1,000 key names. The response might contain fewer keys but will never contain more.
|
||||
- `prefix` - (optional) it can be used to filter objects starting with prefix.
|
||||
- `delimiter` - (optional) it can be used to restrict the results to only the kobjects in the given "directory". Without the delimiter, the entire tree under the prefix is returned
|
||||
|
||||
#### Response
|
||||
|
||||
The response body contains the list of found objects.
|
||||
|
||||
The list of objects will be returned as JSON array in the following form:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"Bucket": "<your bucket>",
|
||||
"Name": "02WGzEdsUWNlQ",
|
||||
"ContentType": "image/png",
|
||||
"ContentLanguage": "",
|
||||
"CacheControl": "",
|
||||
"EventBasedHold": false,
|
||||
"TemporaryHold": false,
|
||||
"RetentionExpirationTime": "0001-01-01T00:00:00Z",
|
||||
"ACL": null,
|
||||
"PredefinedACL": "",
|
||||
"Owner": "",
|
||||
"Size": 5187,
|
||||
"ContentEncoding": "",
|
||||
"ContentDisposition": "",
|
||||
"MD5": "aQdLBCYV0BxA51jUaxc3pQ==",
|
||||
"CRC32C": 1058633505,
|
||||
"MediaLink": "https://storage.googleapis.com/download/storage/v1/b/<your bucket>/o/02WGzEdsUWNlQ?generation=1631553155678071&alt=media",
|
||||
"Metadata": null,
|
||||
"Generation": 1631553155678071,
|
||||
"Metageneration": 1,
|
||||
"StorageClass": "STANDARD",
|
||||
"Created": "2021-09-13T17:12:35.679Z",
|
||||
"Deleted": "0001-01-01T00:00:00Z",
|
||||
"Updated": "2021-09-13T17:12:35.679Z",
|
||||
"CustomerKeySHA256": "",
|
||||
"KMSKeyName": "",
|
||||
"Prefix": "",
|
||||
"Etag": "CPf+mpK5/PICEAE="
|
||||
}
|
||||
]
|
||||
```
|
||||
## Related links
|
||||
|
||||
- [Basic schema for a Dapr component]({{< ref component-schema >}})
|
||||
|
|
|
@ -70,6 +70,8 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
|
||||
## Binding support
|
||||
|
||||
This component supports both **input and output** binding interfaces.
|
||||
|
||||
This component supports **output binding** with the following operations:
|
||||
|
||||
- `create`
|
||||
|
|
|
@ -52,6 +52,7 @@ spec:
|
|||
| authRequired | Y | Input/Output | Enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication with the Kafka brokers. | `"true"`, `"false"` |
|
||||
| saslUsername | N | Input/Output | The SASL username used for authentication. Only required if `authRequired` is set to `"true"`. | `"adminuser"` |
|
||||
| saslPassword | N | Input/Output | The SASL password used for authentication. Can be `secretKeyRef` to use a [secret reference]({{< ref component-secrets.md >}}). Only required if `authRequired` is set to `"true"`. | `""`, `"KeFg23!"` |
|
||||
| initialOffset | N | The initial offset to use if no offset was previously committed. Should be "newest" or "oldest". Defaults to "newest". | `"oldest"` |
|
||||
| maxMessageBytes | N | Input/Output | The maximum size in bytes allowed for a single Kafka message. Defaults to 1024. | `2048` |
|
||||
|
||||
## Binding support
|
||||
|
|
|
@ -38,6 +38,8 @@ spec:
|
|||
value: false
|
||||
- name: maxPriority
|
||||
value: 5
|
||||
- name: contentType
|
||||
value: "text/plain"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
|
@ -56,6 +58,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| prefetchCount | N | Input | Set the [Channel Prefetch Setting (QoS)](https://www.rabbitmq.com/confirms.html#channel-qos-prefetch). If this parameter is omiited, QoS would set value to 0 as no limit | `0` |
|
||||
| exclusive | N | Input/Output | Determines whether the topic will be an exclusive topic or not. Defaults to `"false"` | `"true"`, `"false"` |
|
||||
| maxPriority| N | Input/Output | Parameter to set the [priority queue](https://www.rabbitmq.com/priority.html). If this parameter is omitted, queue will be created as a general queue instead of a priority queue. Value between 1 and 255. See [also](#specifying-a-priority-per-message) | `"1"`, `"10"` |
|
||||
| contentType | N | Input/Output | The content type of the message. Defaults to "text/plain". | `"text/plain"`, `"application/cloudevent+json"` and so on |
|
||||
## Binding support
|
||||
|
||||
This component supports both **input and output** binding interfaces.
|
||||
|
|
|
@ -40,25 +40,26 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
|--------------------|:--------:|------------|-----|---------|
|
||||
| redisHost | Y | Output | The Redis host address | `"localhost:6379"` |
|
||||
| redisPassword | Y | Output | The Redis password | `"password"` |
|
||||
| redisUsername | N | Output | Username for Redis host. Defaults to empty. Make sure your redis server version is 6 or above, and have created acl rule correctly. | `"username"` |
|
||||
| enableTLS | N | Output | If the Redis instance supports TLS with public certificates it can be configured to enable or disable TLS. Defaults to `"false"` | `"true"`, `"false"` |
|
||||
| failover | N | Property to enabled failover configuration. Needs sentinalMasterName to be set. Defaults to `"false"` | `"true"`, `"false"`
|
||||
| sentinelMasterName | N | The sentinel master name. See [Redis Sentinel Documentation](https://redis.io/topics/sentinel) | `""`, `"127.0.0.1:6379"`
|
||||
| redeliverInterval | N | The interval between checking for pending messages to redelivery. Defaults to `"60s"`. `"0"` disables redelivery. | `"30s"`
|
||||
| processingTimeout | N | The amount time a message must be pending before attempting to redeliver it. Defaults to `"15s"`. `"0"` disables redelivery. | `"30s"`
|
||||
| redisType | N | The type of redis. There are two valid values, one is `"node"` for single node mode, the other is `"cluster"` for redis cluster mode. Defaults to `"node"`. | `"cluster"`
|
||||
| redisDB | N | Database selected after connecting to redis. If `"redisType"` is `"cluster"` this option is ignored. Defaults to `"0"`. | `"0"`
|
||||
| redisMaxRetries | N | Maximum number of times to retry commands before giving up. Default is to not retry failed commands. | `"5"`
|
||||
| redisMinRetryInterval | N | Minimum backoff for redis commands between each retry. Default is `"8ms"`; `"-1"` disables backoff. | `"8ms"`
|
||||
| redisMaxRetryInterval | N | Maximum backoff for redis commands between each retry. Default is `"512ms"`;`"-1"` disables backoff. | `"5s"`
|
||||
| dialTimeout | N | Dial timeout for establishing new connections. Defaults to `"5s"`. | `"5s"`
|
||||
| readTimeout | N | Timeout for socket reads. If reached, redis commands will fail with a timeout instead of blocking. Defaults to `"3s"`, `"-1"` for no timeout. | `"3s"`
|
||||
| writeTimeout | N | Timeout for socket writes. If reached, redis commands will fail with a timeout instead of blocking. Defaults is readTimeout. | `"3s"`
|
||||
| poolSize | N | Maximum number of socket connections. Default is 10 connections per every CPU as reported by runtime.NumCPU. | `"20"`
|
||||
| poolTimeout | N | Amount of time client waits for a connection if all connections are busy before returning an error. Default is readTimeout + 1 second. | `"5s"`
|
||||
| maxConnAge | N | Connection age at which the client retires (closes) the connection. Default is to not close aged connections. | `"30m"`
|
||||
| minIdleConns | N | Minimum number of idle connections to keep open in order to avoid the performance degradation associated with creating new connections. Defaults to `"0"`. | `"2"`
|
||||
| idleCheckFrequency | N | Frequency of idle checks made by idle connections reaper. Default is `"1m"`. `"-1"` disables idle connections reaper. | `"-1"`
|
||||
| idleTimeout | N | Amount of time after which the client closes idle connections. Should be less than server's timeout. Default is `"5m"`. `"-1"` disables idle timeout check. | `"10m"`
|
||||
| failover | N | Output | Property to enabled failover configuration. Needs sentinalMasterName to be set. Defaults to `"false"` | `"true"`, `"false"`
|
||||
| sentinelMasterName | N | Output | The sentinel master name. See [Redis Sentinel Documentation](https://redis.io/topics/sentinel) | `""`, `"127.0.0.1:6379"`
|
||||
| redeliverInterval | N | Output | The interval between checking for pending messages to redelivery. Defaults to `"60s"`. `"0"` disables redelivery. | `"30s"`
|
||||
| processingTimeout | N | Output | The amount time a message must be pending before attempting to redeliver it. Defaults to `"15s"`. `"0"` disables redelivery. | `"30s"`
|
||||
| redisType | N | Output | The type of redis. There are two valid values, one is `"node"` for single node mode, the other is `"cluster"` for redis cluster mode. Defaults to `"node"`. | `"cluster"`
|
||||
| redisDB | N | Output | Database selected after connecting to redis. If `"redisType"` is `"cluster"` this option is ignored. Defaults to `"0"`. | `"0"`
|
||||
| redisMaxRetries | N | Output | Maximum number of times to retry commands before giving up. Default is to not retry failed commands. | `"5"`
|
||||
| redisMinRetryInterval | N | Output | Minimum backoff for redis commands between each retry. Default is `"8ms"`; `"-1"` disables backoff. | `"8ms"`
|
||||
| redisMaxRetryInterval | N | Output | Maximum backoff for redis commands between each retry. Default is `"512ms"`;`"-1"` disables backoff. | `"5s"`
|
||||
| dialTimeout | N | Output | Dial timeout for establishing new connections. Defaults to `"5s"`. | `"5s"`
|
||||
| readTimeout | N | Output | Timeout for socket reads. If reached, redis commands will fail with a timeout instead of blocking. Defaults to `"3s"`, `"-1"` for no timeout. | `"3s"`
|
||||
| writeTimeout | N | Output | Timeout for socket writes. If reached, redis commands will fail with a timeout instead of blocking. Defaults is readTimeout. | `"3s"`
|
||||
| poolSize | N | Output | Maximum number of socket connections. Default is 10 connections per every CPU as reported by runtime.NumCPU. | `"20"`
|
||||
| poolTimeout | N | Output | Amount of time client waits for a connection if all connections are busy before returning an error. Default is readTimeout + 1 second. | `"5s"`
|
||||
| maxConnAge | N | Output | Connection age at which the client retires (closes) the connection. Default is to not close aged connections. | `"30m"`
|
||||
| minIdleConns | N | Output | Minimum number of idle connections to keep open in order to avoid the performance degradation associated with creating new connections. Defaults to `"0"`. | `"2"`
|
||||
| idleCheckFrequency | N | Output | Frequency of idle checks made by idle connections reaper. Default is `"1m"`. `"-1"` disables idle connections reaper. | `"-1"`
|
||||
| idleTimeout | N | Output | Amount of time after which the client closes idle connections. Should be less than server's timeout. Default is `"5m"`. `"-1"` disables idle timeout check. | `"10m"`
|
||||
|
||||
|
||||
## Binding support
|
||||
|
|
|
@ -33,6 +33,10 @@ spec:
|
|||
value: *****************
|
||||
- name: sessionToken
|
||||
value: mysession
|
||||
- name: decodeBase64
|
||||
value: <bool>
|
||||
- name: encodeBase64
|
||||
value: <bool>
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
|
@ -48,13 +52,18 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| accessKey | Y | Output | The AWS Access Key to access this resource | `"key"` |
|
||||
| secretKey | Y | Output | The AWS Secret Access Key to access this resource | `"secretAccessKey"` |
|
||||
| sessionToken | N | Output | The AWS session token to use | `"sessionToken"` |
|
||||
| decodeBase64 | N | Output | Configuration to decode base64 file content before saving to bucket storage. (In case of saving a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
| encodeBase64 | N | Output | Configuration to encode base64 file content before return the content. (In case of opening a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
|
||||
|
||||
## Binding support
|
||||
|
||||
This component supports **output binding** with the following operations:
|
||||
|
||||
- `create`
|
||||
- `create` : [Create file](#create-file)
|
||||
- `get` : [Get file](#get-file)
|
||||
- `delete` : [Delete file](#delete-file)
|
||||
- `list`: [List file](#list-files)
|
||||
|
||||
### Create file
|
||||
|
||||
|
@ -70,8 +79,6 @@ To perform a create operation, invoke the AWS S3 binding with a `POST` method an
|
|||
```
|
||||
|
||||
#### Examples
|
||||
|
||||
|
||||
##### Save text to a random generated UUID file
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
@ -111,10 +118,33 @@ To perform a create operation, invoke the AWS S3 binding with a `POST` method an
|
|||
|
||||
{{< /tabs >}}
|
||||
|
||||
##### Save a file to a object
|
||||
|
||||
##### Upload a file
|
||||
To upload a file, encode it as Base64 and let the Binding know to deserialize it:
|
||||
|
||||
To upload a file, pass the file contents as the data payload; you may want to encode this in e.g. Base64 for binary content.
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: <NAME>
|
||||
namespace: <NAMESPACE>
|
||||
spec:
|
||||
type: bindings.aws.s3
|
||||
version: v1
|
||||
metadata:
|
||||
- name: bucket
|
||||
value: mybucket
|
||||
- name: region
|
||||
value: us-west-2
|
||||
- name: accessKey
|
||||
value: *****************
|
||||
- name: secretKey
|
||||
value: *****************
|
||||
- name: sessionToken
|
||||
value: mysession
|
||||
- name: decodeBase64
|
||||
value: <bool>
|
||||
```
|
||||
|
||||
Then you can upload it as you would normally:
|
||||
|
||||
|
@ -122,19 +152,172 @@ Then you can upload it as you would normally:
|
|||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"(YOUR_FILE_CONTENTS)\", \"metadata\": { \"key\": \"my-test-file.jpg\" } }" http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"YOUR_BASE_64_CONTENT\", \"metadata\": { \"key\": \"my-test-file.jpg\" } }" http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "create", "data": "$(cat my-test-file.jpg)", "metadata": { "key": "my-test-file.jpg" } }' \
|
||||
curl -d '{ "operation": "create", "data": "YOUR_BASE_64_CONTENT", "metadata": { "key": "my-test-file.jpg" } }' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
#### Response
|
||||
|
||||
The response body will contain the following JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"location":"https://<your bucket>.s3.<your region>.amazonaws.com/<key>",
|
||||
"versionID":"<version ID if Bucket Versioning is enabled"
|
||||
}
|
||||
```
|
||||
|
||||
### Get object
|
||||
|
||||
To perform a get file operation, invoke the AWS S3 binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "get",
|
||||
"metadata": {
|
||||
"key": "my-test-file.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The metadata parameters are:
|
||||
|
||||
- `key` - the name of the object
|
||||
|
||||
#### Example
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ \"operation\": \"get\", \"metadata\": { \"key\": \"my-test-file.txt\" }}' http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "get", "metadata": { "key": "my-test-file.txt" }}' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
#### Response
|
||||
|
||||
The response body contains the value stored in the object.
|
||||
|
||||
|
||||
### Delete object
|
||||
|
||||
To perform a delete object operation, invoke the AWS S3 binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "delete",
|
||||
"metadata": {
|
||||
"key": "my-test-file.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The metadata parameters are:
|
||||
|
||||
- `key` - the name of the object
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
##### Delete object
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ \"operation\": \"delete\", \"metadata\": { \"key\": \"my-test-file.txt\" }}' http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "delete", "metadata": { "key": "my-test-file.txt" }}' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
#### Response
|
||||
|
||||
An HTTP 204 (No Content) and empty body will be retuned if successful.
|
||||
|
||||
|
||||
### List objects
|
||||
|
||||
To perform a list object operation, invoke the S3 binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "list",
|
||||
"data": {
|
||||
"maxResults": 10,
|
||||
"prefix": "file",
|
||||
"marker": "hvlcCQFSOD5TD",
|
||||
"delimiter": "i0FvxAn2EOEL6"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The data parameters are:
|
||||
|
||||
- `maxResults` - (optional) sets the maximum number of keys returned in the response. By default the action returns up to 1,000 key names. The response might contain fewer keys but will never contain more.
|
||||
- `prefix` - (optional) limits the response to keys that begin with the specified prefix.
|
||||
- `marker` - (optional) marker is where you want Amazon S3 to start listing from. Amazon S3 starts listing after this specified key. Marker can be any key in the bucket.
|
||||
The marker value may then be used in a subsequent call to request the next set of list items.
|
||||
- `delimiter` - (optional) A delimiter is a character you use to group keys.
|
||||
|
||||
|
||||
#### Response
|
||||
|
||||
The response body contains the list of found objects.
|
||||
|
||||
The list of objects will be returned as JSON array in the following form:
|
||||
|
||||
```json
|
||||
{
|
||||
"CommonPrefixes": null,
|
||||
"Contents": [
|
||||
{
|
||||
"ETag": "\"7e94cc9b0f5226557b05a7c2565dd09f\"",
|
||||
"Key": "hpNdFUxruNuwm",
|
||||
"LastModified": "2021-08-16T06:44:14Z",
|
||||
"Owner": {
|
||||
"DisplayName": "owner name",
|
||||
"ID": "owner id"
|
||||
},
|
||||
"Size": 6916,
|
||||
"StorageClass": "STANDARD"
|
||||
}
|
||||
],
|
||||
"Delimiter": "",
|
||||
"EncodingType": null,
|
||||
"IsTruncated": true,
|
||||
"Marker": "hvlcCQFSOD5TD",
|
||||
"MaxKeys": 1,
|
||||
"Name": "mybucketdapr",
|
||||
"NextMarker": "hzaUPWjmvyi9W",
|
||||
"Prefix": ""
|
||||
}
|
||||
```
|
||||
## Related links
|
||||
|
||||
- [Basic schema for a Dapr component]({{< ref component-schema >}})
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
type: docs
|
||||
title: "AWS SES binding spec"
|
||||
linkTitle: "AWS SES"
|
||||
description: "Detailed documentation on the AWS SES binding component"
|
||||
aliases:
|
||||
- "/operations/components/setup-bindings/supported-bindings/ses/"
|
||||
---
|
||||
|
||||
## Component format
|
||||
|
||||
To setup AWS binding create a component of type `bindings.aws.ses`. See [this guide]({{< ref "howto-bindings.md#1-create-a-binding" >}}) on how to create and apply a binding configuration.
|
||||
|
||||
See [Authenticating to AWS]({{< ref authenticating-aws.md >}}) for information about authentication-related attributes
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: ses
|
||||
namespace: default
|
||||
spec:
|
||||
type: bindings.aws.ses
|
||||
version: v1
|
||||
metadata:
|
||||
- name: accessKey
|
||||
value: *****************
|
||||
- name: secretKey
|
||||
value: *****************
|
||||
- name: region
|
||||
value: "eu-west-1"
|
||||
- name: sessionToken
|
||||
value: mysession
|
||||
- name: emailFrom
|
||||
value: "sender@example.com"
|
||||
- name: emailTo
|
||||
value: "receiver@example.com"
|
||||
- name: emailCc
|
||||
value: "cc@example.com"
|
||||
- name: emailBcc
|
||||
value: "bcc@example.com"
|
||||
- name: subject
|
||||
value: "subject"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Binding support | Details | Example |
|
||||
|--------------------|:--------:|------------|-----|---------|
|
||||
| region | Y | Output | The specific AWS region | `"eu-west-1"` |
|
||||
| accessKey | Y | Output | The AWS Access Key to access this resource | `"key"` |
|
||||
| secretKey | Y | Output | The AWS Secret Access Key to access this resource | `"secretAccessKey"` |
|
||||
| sessionToken | N | Output | The AWS session token to use | `"sessionToken"` |
|
||||
| emailFrom | N | Output | If set, this specifies the email address of the sender. See [also](#example-request) | `"me@example.com"` |
|
||||
| emailTo | N | Output | If set, this specifies the email address of the receiver. See [also](#example-request) | `"me@example.com"` |
|
||||
| emailCc | N | Output | If set, this specifies the email address to CC in. See [also](#example-request) | `"me@example.com"` |
|
||||
| emailBcc | N | Output | If set, this specifies email address to BCC in. See [also](#example-request) | `"me@example.com"` |
|
||||
| subject | N | Output | If set, this specifies the subject of the email message. See [also](#example-request) | `"subject of mail"` |
|
||||
|
||||
|
||||
|
||||
## Binding support
|
||||
|
||||
This component supports **output binding** with the following operations:
|
||||
|
||||
- `create`
|
||||
|
||||
## Example request
|
||||
|
||||
You can specify any of the following optional metadata properties with each request:
|
||||
|
||||
- `emailFrom`
|
||||
- `emailTo`
|
||||
- `emailCc`
|
||||
- `emailBcc`
|
||||
- `subject`
|
||||
|
||||
When sending an email, the metadata in the configuration and in the request is combined. The combined set of metadata must contain at least the `emailFrom`, `emailTo`, `emailCc`, `emailBcc` and `subject` fields.
|
||||
|
||||
The `emailTo`, `emailCc` and `emailBcc` fields can contain multiple email addresses separated by a semicolon.
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"operation": "create",
|
||||
"metadata": {
|
||||
"emailTo": "dapr-smtp-binding@example.net",
|
||||
"emailCc": "cc1@example.net",
|
||||
"subject": "Email subject"
|
||||
},
|
||||
"data": "Testing Dapr SMTP Binding"
|
||||
}
|
||||
```
|
||||
The `emailTo`, `emailCc` and `emailBcc` fields can contain multiple email addresses separated by a semicolon.
|
||||
## Related links
|
||||
|
||||
- [Basic schema for a Dapr component]({{< ref component-schema >}})
|
||||
- [Bindings building block]({{< ref bindings >}})
|
||||
- [How-To: Trigger application with input binding]({{< ref howto-triggers.md >}})
|
||||
- [How-To: Use bindings to interface with external resources]({{< ref howto-bindings.md >}})
|
||||
- [Bindings API reference]({{< ref bindings_api.md >}})
|
|
@ -30,6 +30,8 @@ spec:
|
|||
value: "myqueue"
|
||||
- name: ttlInSeconds
|
||||
value: "60"
|
||||
- name: decodeBase64
|
||||
value: "false"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
|
@ -44,6 +46,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| storageAccessKey | Y | Input/Output | The Azure Storage access key | `"accessKey"` |
|
||||
| queue | Y | Input/Output | The name of the Azure Storage queue | `"myqueue"` |
|
||||
| ttlInSeconds | N | Output | Parameter to set the default message time to live. If this parameter is omitted, messages will expire after 10 minutes. See [also](#specifying-a-ttl-per-message) | `"60"` |
|
||||
| decodeBase64 | N | Output | Configuration to decode base64 file content before saving to Blob Storage. (In case of saving a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
|
||||
## Binding support
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ Table captions:
|
|||
| [Hazelcast]({{< ref setup-hazelcast.md >}}) | Alpha | v1 | 1.0 |
|
||||
| [MQTT]({{< ref setup-mqtt.md >}}) | Alpha | v1 | 1.0 |
|
||||
| [NATS Streaming]({{< ref setup-nats-streaming.md >}}) | Beta | v1 | 1.0 |
|
||||
| [In Memory]({{< ref setup-inmemory.md >}}) | Alpha | v1 | 1.4 |
|
||||
| [JetStream]({{< ref setup-jetstream.md >}}) | Alpha | v1 | 1.4 |
|
||||
| [Pulsar]({{< ref setup-pulsar.md >}}) | Alpha | v1 | 1.0 |
|
||||
| [RabbitMQ]({{< ref setup-rabbitmq.md >}}) | Alpha | v1 | 1.0 |
|
||||
| [Redis Streams]({{< ref setup-redis-pubsub.md >}}) | GA | v1 | 1.0 |
|
||||
|
|
|
@ -49,6 +49,7 @@ spec:
|
|||
| authRequired | Y | Enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication with the Kafka brokers. | `"true"`, `"false"`
|
||||
| saslUsername | N | The SASL username used for authentication. Only required if `authRequired` is set to `"true"`. | `"adminuser"`
|
||||
| saslPassword | N | The SASL password used for authentication. Can be `secretKeyRef` to use a [secret reference]({{< ref component-secrets.md >}}). Only required if `authRequired` is set to `"true"`. | `""`, `"KeFg23!"`
|
||||
| initialOffset | N | The initial offset to use if no offset was previously committed. Should be "newest" or "oldest". Defaults to "newest". | `"oldest"`
|
||||
| maxMessageBytes | N | The maximum size in bytes allowed for a single Kafka message. Defaults to 1024. | `2048`
|
||||
|
||||
## Per-call metadata fields
|
||||
|
|
|
@ -84,6 +84,40 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| publishMaxRetries | N | The max number of retries for when Azure Service Bus responds with "too busy" in order to throttle messages. Defaults: `5` | `5`
|
||||
| publishInitialRetryInternalInMs | N | Time in milliseconds for the initial exponential backoff when Azure Service Bus throttle messages. Defaults: `500` | `500`
|
||||
|
||||
## Message metadata
|
||||
|
||||
Azure Service Bus messages extend the Dapr message format with additional contextual metadata. Some metadata fields are set by Azure Service Bus itself (read-only) and others can be set by the client when publishing a message.
|
||||
|
||||
### Sending a message with metadata
|
||||
|
||||
To set Azure Service Bus metadata when sending a message, set the query parameters on the HTTP request or the gRPC metadata as documented [here](https://docs.dapr.io/reference/api/pubsub_api/#metadata).
|
||||
|
||||
- `metadata.MessageId`
|
||||
- `metadata.CorrelationId`
|
||||
- `metadata.SessionId`
|
||||
- `metadata.Label`
|
||||
- `metadata.ReplyTo`
|
||||
- `metadata.PartitionKey`
|
||||
- `metadata.To`
|
||||
- `metadata.ContentType`
|
||||
- `metadata.ScheduledEnqueueTimeUtc`
|
||||
- `metadata.ReplyToSessionId`
|
||||
|
||||
> **NOTE:** The `metadata.MessageId` property does not set the `id` property of the cloud event and should be treated in isolation.
|
||||
|
||||
### Receiving a message with metadata
|
||||
|
||||
When Dapr calls your application, it will attach Azure Service Bus message metadata to the request using either HTTP headers or gRPC metadata.
|
||||
In addition to the [settable metadata listed above](#sending-a-message-with-metadata), you can also access the following read-only message metadata.
|
||||
|
||||
- `metadata.DeliveryCount`
|
||||
- `metadata.LockedUntilUtc`
|
||||
- `metadata.LockToken`
|
||||
- `metadata.EnqueuedTimeUtc`
|
||||
- `metadata.SequenceNumber`
|
||||
|
||||
To find out more details on the purpose of any of these metadata properties, please refer to [the official Azure Service Bus documentation](https://docs.microsoft.com/en-us/rest/api/servicebus/message-headers-and-properties#message-headers).
|
||||
|
||||
## Create an Azure Service Bus
|
||||
|
||||
Follow the instructions [here](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quickstart-topics-subscriptions-portal) on setting up Azure Service Bus Topics.
|
||||
|
|
|
@ -46,6 +46,8 @@ spec:
|
|||
value: <PRIVATE_KEY> # replace x509 cert
|
||||
- name: disableEntityManagement
|
||||
value: "false"
|
||||
- name: enableMessageOrdering
|
||||
value: "false"
|
||||
```
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
|
||||
|
@ -67,6 +69,11 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| authProviderX509CertUrl | N | If using explicit credentials, this field should contain the `auth_provider_x509_cert_url` field from the service account json | `https://www.googleapis.com/oauth2/v1/certs`
|
||||
| clientX509CertUrl | N | If using explicit credentials, this field should contain the `client_x509_cert_url` field from the service account json | `https://www.googleapis.com/robot/v1/metadata/x509/myserviceaccount%40myproject.iam.gserviceaccount.com`
|
||||
| disableEntityManagement | N | When set to `"true"`, topics and subscriptions do not get created automatically. Default: `"false"` | `"true"`, `"false"`
|
||||
| enableMessageOrdering | N | When set to `"true"`, subscribed messages will be received in order, depending on publishing and permissions configuration. | `"true"`, `"false"`
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
If `enableMessageOrdering` is set to "true", the roles/viewer or roles/pubsub.viewer role will be required on the service account in order to guarantee ordering in cases where order tokens are not embedded in the messages. If this role is not given, or the call to Subscription.Config() fails for any other reason, ordering by embedded order tokens will still function correctly.
|
||||
{{% /alert %}}
|
||||
|
||||
## Create a GCP Pub/Sub
|
||||
You can use either "explicit" or "implicit" credentials to configure access to your GCP pubsub instance. If using explicit, most fields are required. Implicit relies on dapr running under a Kubernetes service account (KSA) mapped to a Google service account (GSA) which has the necessary permissions to access pubsub. In implicit mode, only the `projectId` attribute is needed, all other are optional.
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
type: docs
|
||||
title: "In Memory"
|
||||
linkTitle: "In Memory"
|
||||
description: "Detailed documentation on the In Memory pubsub component"
|
||||
aliases:
|
||||
- "/operations/components/setup-pubsub/supported-pubsub/setup-inmemory/"
|
||||
---
|
||||
|
||||
The In Memory pub/sub component is useful for development purposes and works inside of a single machine boundary.
|
||||
|
||||
## Component format
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: pubsub
|
||||
namespace: default
|
||||
spec:
|
||||
type: pubsub.in-memory
|
||||
version: v1
|
||||
```
|
||||
|
||||
## Related links
|
||||
- [Basic schema for a Dapr component]({{< ref component-schema >}}) in the Related links section
|
||||
- Read [this guide]({{< ref "howto-publish-subscribe.md#step-2-publish-a-topic" >}}) for instructions on configuring pub/sub components
|
||||
- [Pub/Sub building block]({{< ref pubsub >}})
|
|
@ -0,0 +1,97 @@
|
|||
---
|
||||
type: docs
|
||||
title: "JetStream"
|
||||
linkTitle: "JetStream"
|
||||
description: "Detailed documentation on the NATS JetStream component"
|
||||
aliases:
|
||||
- "/operations/components/setup-pubsub/supported-pubsub/setup-jetstream/"
|
||||
---
|
||||
|
||||
## Component format
|
||||
To setup JetStream pubsub create a component of type `pubsub.jetstream`. See
|
||||
[this guide]({{< ref
|
||||
"howto-publish-subscribe.md#step-1-setup-the-pubsub-component" >}}) on how to
|
||||
create and apply a pubsub configuration.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: jetstream-pubsub
|
||||
namespace: default
|
||||
spec:
|
||||
type: pubsub.jetstream
|
||||
version: v1
|
||||
metadata:
|
||||
- name: natsURL
|
||||
value: "nats://localhost:4222"
|
||||
- name: name
|
||||
value: "connection name"
|
||||
- name: durableName
|
||||
value: "consumer durable name"
|
||||
- name: queueGroupName
|
||||
value: "queue group name"
|
||||
- name: startSequence
|
||||
value: 1
|
||||
- name: startTime # in Unix format
|
||||
value: 1630349391
|
||||
- name: deliverAll
|
||||
value: false
|
||||
- name: flowControl
|
||||
value: false
|
||||
```
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|----------------|:--------:|---------|---------|
|
||||
| natsURL | Y | NATS server address URL | "`nats://localhost:4222`"|
|
||||
| name | N | NATS connection name | `"my-conn-name"`|
|
||||
| durableName | N | [Durable name] | `"my-durable"` |
|
||||
| queueGroupName | N | Queue group name | `"my-queue"` |
|
||||
| startSequence | N | [Start Sequence] | `1` |
|
||||
| startTime | N | [Start Time] in Unix format | `1630349391` |
|
||||
| deliverAll | N | Set deliver all as [Replay Policy] | `true` |
|
||||
| flowControl | N | [Flow Control] | `true` |
|
||||
|
||||
## Create a NATS server
|
||||
|
||||
{{< tabs "Self-Hosted" "Kubernetes">}}
|
||||
|
||||
{{% codetab %}}
|
||||
You can run a NATS Server with JetStream enabled locally using Docker:
|
||||
|
||||
```bash
|
||||
docker run -d -p 4222:4222 nats:latest -js
|
||||
```
|
||||
|
||||
You can then interact with the server using the client port: `localhost:4222`.
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
Install NATS JetStream on Kubernetes by using the [helm](https://github.com/nats-io/k8s/tree/main/helm/charts/nats#jetstream):
|
||||
|
||||
```bash
|
||||
helm repo add nats https://nats-io.github.io/k8s/helm/charts/
|
||||
helm install my-nats nats/nats
|
||||
```
|
||||
|
||||
This installs a single NATS server into the `default` namespace. To interact
|
||||
with NATS, find the service with: `kubectl get svc my-nats`.
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
## Related links
|
||||
- [Basic schema for a Dapr component]({{< ref component-schema >}})
|
||||
- Read [this guide]({{< ref "howto-publish-subscribe.md#step-2-publish-a-topic" >}}) for instructions on configuring pub/sub components
|
||||
- [Pub/Sub building block]({{< ref pubsub >}})
|
||||
- [JetStream Documentation](https://docs.nats.io/jetstream/jetstream)
|
||||
- [NATS CLI](https://github.com/nats-io/natscli)
|
||||
|
||||
|
||||
[Durable Name]: https://docs.nats.io/jetstream/concepts/consumers#durable-name
|
||||
[Start Sequence]: https://docs.nats.io/jetstream/concepts/consumers#deliverbystartsequence
|
||||
[Start Time]: https://docs.nats.io/jetstream/concepts/consumers#deliverbystarttime
|
||||
[Replay Policy]: https://docs.nats.io/jetstream/concepts/consumers#replaypolicy
|
||||
[Flow Control]: https://docs.nats.io/jetstream/concepts/consumers#flowcontrol
|
|
@ -54,6 +54,11 @@ spec:
|
|||
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
NATS Streaming has been [deprecated](https://github.com/nats-io/nats-streaming-server/#warning--deprecation-notice-warning).
|
||||
Please consider using [NATS JetStream]({{< ref setup-jetstream >}}) going forward.
|
||||
{{% /alert %}}
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|
@ -111,3 +116,4 @@ For example, if installing using the example above, the NATS Streaming address w
|
|||
- [Basic schema for a Dapr component]({{< ref component-schema >}})
|
||||
- Read [this guide]({{< ref "howto-publish-subscribe.md#step-2-publish-a-topic" >}}) for instructions on configuring pub/sub components
|
||||
- [Pub/Sub building block]({{< ref pubsub >}})
|
||||
- [NATS Streaming Deprecation Notice](https://github.com/nats-io/nats-streaming-server/#warning--deprecation-notice-warning)
|
||||
|
|
|
@ -41,6 +41,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
|--------------------|:--------:|---------|---------|
|
||||
| redisHost | Y | Connection-string for the redis host. If `"redisType"` is `"cluster"` it can be multiple hosts separated by commas or just a single host | `localhost:6379`, `redis-master.default.svc.cluster.local:6379`
|
||||
| redisPassword | Y | Password for Redis host. No Default. Can be `secretKeyRef` to use a secret reference | `""`, `"KeFg23!"`
|
||||
| redisUsername | N | Username for Redis host. Defaults to empty. Make sure your redis server version is 6 or above, and have created acl rule correctly. | `""`, `"default"`
|
||||
| consumerID | N | The consumer group ID | `"myGroup"`
|
||||
| enableTLS | N | If the Redis instance supports TLS with public certificates, can be configured to be enabled or disabled. Defaults to `"false"` | `"true"`, `"false"`
|
||||
| redeliverInterval | N | The interval between checking for pending messages to redelivery. Defaults to `"60s"`. `"0"` disables redelivery. | `"30s"`
|
||||
|
|
|
@ -45,5 +45,4 @@ Table captions:
|
|||
|
||||
| Name | Status | Component version | Since |
|
||||
|---------------------------------------------------------------------------------------|--------| ---- |--------------|
|
||||
| [Azure Key Vault w/ Managed Identity]({{< ref azure-keyvault-managed-identity.md >}}) | Alpha | v1 | 1.0 |
|
||||
| [Azure Key Vault]({{< ref azure-keyvault.md >}}) | GA | v1 | 1.0 |
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
---
|
||||
type: docs
|
||||
title: "Azure Key Vault with Managed Identities on Kubernetes"
|
||||
linkTitle: "Azure Key Vault w/ Managed Identity"
|
||||
description: How to configure Azure Key Vault and Kubernetes to use Azure Managed Identities to access secrets
|
||||
aliases:
|
||||
- "/operations/components/setup-secret-store/supported-secret-stores/azure-keyvault-managed-identity/"
|
||||
---
|
||||
|
||||
## Component format
|
||||
|
||||
To setup Azure Key Vault secret store with Managed Identies create a component of type `secretstores.azure.keyvault`. See [this guide]({{< ref "setup-secret-store.md#apply-the-configuration" >}}) on how to create and apply a secretstore configuration. See this guide on [referencing secrets]({{< ref component-secrets.md >}}) to retrieve and use the secret with Dapr components.
|
||||
|
||||
In Kubernetes mode, you store the certificate for the service principal into the Kubernetes Secret Store and then enable Azure Key Vault secret store with this certificate in Kubernetes secretstore.
|
||||
|
||||
The component yaml uses the name of your key vault and the Client ID of the managed identity to setup the secret store.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: [your_keyvault_name]
|
||||
- name: spnClientId
|
||||
value: [your_managed_identity_client_id]
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
The above example uses secrets as plain strings. It is recommended to use a local secret store such as [Kubernetes secret store]({{< ref kubernetes-secret-store.md >}}) or a [local file]({{< ref file-secret-store.md >}}) to bootstrap secure key storage.
|
||||
{{% /alert %}}
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|--------------------|:--------:|-------------------------------------------------------------------------|---------------------|
|
||||
| vaultName | Y | The name of the Azure Key Vault | `"mykeyvault"` |
|
||||
| spnClientId | Y | Your managed identity client Id | `"yourId"` |
|
||||
|
||||
## Setup Managed Identity and Azure Key Vault
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Azure Subscription](https://azure.microsoft.com/en-us/free/)
|
||||
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
|
||||
|
||||
### Steps
|
||||
|
||||
1. Login to Azure and set the default subscription
|
||||
|
||||
```bash
|
||||
# Log in Azure
|
||||
az login
|
||||
|
||||
# Set your subscription to the default subscription
|
||||
az account set -s [your subscription id]
|
||||
```
|
||||
|
||||
2. Create an Azure Key Vault in a region
|
||||
|
||||
```bash
|
||||
az keyvault create --location [region] --name [your keyvault] --resource-group [your resource group]
|
||||
```
|
||||
|
||||
3. Create the managed identity(Optional)
|
||||
|
||||
This step is required only if the AKS Cluster is provisoned without the flag "--enable-managed-identity". If the cluster is provisioned with managed identity, than it is suggested to use the autogenerated managed identity that is associated to the Resource Group MC_*.
|
||||
|
||||
```bash
|
||||
$identity = az identity create -g [your resource group] -n [your managed identity name] -o json | ConvertFrom-Json
|
||||
```
|
||||
|
||||
Below is the command to retrieve the managed identity in the autogenerated scenario:
|
||||
|
||||
```bash
|
||||
az aks show -g <AKSResourceGroup> -n <AKSClusterName>
|
||||
```
|
||||
For more detail about the roles to assign to integrate AKS with Azure Services [Role Assignment](https://azure.github.io/aad-pod-identity/docs/getting-started/role-assignment/).
|
||||
|
||||
4. Retrieve Managed Identity ID
|
||||
|
||||
The two main scenario are:
|
||||
- Service Principal, in this case the Resource Group is the one in which is deployed the AKS Service Cluster
|
||||
|
||||
```bash
|
||||
$clientId= az aks show -g <AKSResourceGroup> -n <AKSClusterName> --query servicePrincipalProfile.clientId -otsv
|
||||
```
|
||||
|
||||
- Managed Identity, in this case the Resource Group is the one in which is deployed the AKS Service Cluster
|
||||
|
||||
```bash
|
||||
$clientId= az aks show -g <AKSResourceGroup> -n <AKSClusterName> --query identityProfile.kubeletidentity.clientId -otsv
|
||||
```
|
||||
|
||||
5. Assign the Reader role to the managed identity
|
||||
|
||||
For AKS cluster, the cluster resource group refers to the resource group with a MC_ prefix, which contains all of the infrastructure resources associated with the cluster like VM/VMSS.
|
||||
|
||||
```bash
|
||||
az role assignment create --role "Reader" --assignee $clientId --scope /subscriptions/[your subscription id]/resourcegroups/[your resource group]
|
||||
```
|
||||
|
||||
6. Assign the Managed Identity Operator role to the AKS Service Principal
|
||||
Refer to previous step about the Resource Group to use and which identity to assign
|
||||
```bash
|
||||
az role assignment create --role "Managed Identity Operator" --assignee $clientId --scope /subscriptions/[your subscription id]/resourcegroups/[your resource group]
|
||||
|
||||
az role assignment create --role "Virtual Machine Contributor" --assignee $clientId --scope /subscriptions/[your subscription id]/resourcegroups/[your resource group]
|
||||
```
|
||||
|
||||
7. Add a policy to the Key Vault so the managed identity can read secrets
|
||||
|
||||
```bash
|
||||
az keyvault set-policy --name [your keyvault] --spn $clientId --secret-permissions get list
|
||||
```
|
||||
|
||||
8. Enable AAD Pod Identity on AKS
|
||||
|
||||
```bash
|
||||
kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
|
||||
|
||||
# For AKS clusters, deploy the MIC and AKS add-on exception by running -
|
||||
kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/mic-exception.yaml
|
||||
```
|
||||
|
||||
9. Configure the Azure Identity and AzureIdentityBinding yaml
|
||||
|
||||
Save the following yaml as azure-identity-config.yaml:
|
||||
|
||||
```yaml
|
||||
apiVersion: "aadpodidentity.k8s.io/v1"
|
||||
kind: AzureIdentity
|
||||
metadata:
|
||||
name: [your managed identity name]
|
||||
spec:
|
||||
type: 0
|
||||
resourceID: [your managed identity id]
|
||||
clientID: [your managed identity Client ID]
|
||||
---
|
||||
apiVersion: "aadpodidentity.k8s.io/v1"
|
||||
kind: AzureIdentityBinding
|
||||
metadata:
|
||||
name: [your managed identity name]-identity-binding
|
||||
spec:
|
||||
azureIdentity: [your managed identity name]
|
||||
selector: [your managed identity selector]
|
||||
```
|
||||
|
||||
10. Deploy the azure-identity-config.yaml:
|
||||
|
||||
```yaml
|
||||
kubectl apply -f azure-identity-config.yaml
|
||||
```
|
||||
|
||||
## References
|
||||
- [Azure CLI Keyvault CLI](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)
|
||||
- [Create an Azure service principal with Azure CLI](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest)
|
||||
- [AAD Pod Identity](https://github.com/Azure/aad-pod-identity)
|
||||
- [Secrets building block]({{< ref secrets >}})
|
||||
- [How-To: Retrieve a secret]({{< ref "howto-secrets.md" >}})
|
||||
- [How-To: Reference secrets in Dapr components]({{< ref component-secrets.md >}})
|
||||
- [Secrets API reference]({{< ref secrets_api.md >}})
|
|
@ -7,10 +7,6 @@ aliases:
|
|||
- "/operations/components/setup-secret-store/supported-secret-stores/azure-keyvault/"
|
||||
---
|
||||
|
||||
{{% alert title="Note" color="primary" %}}
|
||||
Azure Managed Identity can be used for Azure Key Vault access on Kubernetes. Instructions [here]({{< ref azure-keyvault-managed-identity.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
## Component format
|
||||
|
||||
To setup Azure Key Vault secret store create a component of type `secretstores.azure.keyvault`. See [this guide]({{< ref "setup-secret-store.md#apply-the-configuration" >}}) on how to create and apply a secretstore configuration. See this guide on [referencing secrets]({{< ref component-secrets.md >}}) to retrieve and use the secret with Dapr components.
|
||||
|
@ -37,158 +33,91 @@ spec:
|
|||
- name: spnCertificateFile
|
||||
value : "[pfx_certificate_file_fully_qualified_local_path]"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
The above example uses secrets as plain strings. It is recommended to use a local secret store such as [Kubernetes secret store]({{< ref kubernetes-secret-store.md >}}) or a [local file]({{< ref file-secret-store.md >}}) to bootstrap secure key storage.
|
||||
{{% /alert %}}
|
||||
|
||||
## Spec metadata fields
|
||||
## Authenticating with Azure AD
|
||||
|
||||
### Self-Hosted
|
||||
The Azure Key Vault secret store component supports authentication with Azure AD only. Before you enable this component, make sure you've read the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document and created an Azure AD application (also called Service Principal). Alternatively, make sure you have created a managed identity for your application platform.
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|--------------------|:--------:|---------|---------|
|
||||
| vaultName | Y | The name of the Azure Key Vault. If you only provide a name, it will covert to `[your_keyvault_name].vault.azure.net` in Dapr. If your URL uses another suffix, please provide the entire URI, such as `test.vault.azure.cn`. | `"mykeyvault"`, `"mykeyvault.value.azure.cn"`
|
||||
| spnTenantId | Y | Service Principal Tenant Id | `"spnTenantId"`
|
||||
| spnClientId | Y | Service Principal App Id | `"spnAppId"`
|
||||
| spnCertificateFile | Y | PFX certificate file path. <br></br> For Windows the `[pfx_certificate_file_fully_qualified_local_path]` value must use escaped backslashes, i.e. double backslashes. For example `"C:\\folder1\\folder2\\certfile.pfx"`. <br></br> For Linux you can use single slashes. For example `"/folder1/folder2/certfile.pfx"`. <br></br> See [configure the component](#configure-the-component) for more details | `"C:\\folder1\\folder2\\certfile.pfx"`, `"/folder1/folder2/certfile.pfx"`
|
||||
| `vaultName` | Y | The name of the Azure Key Vault | `"mykeyvault"` |
|
||||
| `azureEnvironment` | N | Optional name for the Azure environment if using a different Azure cloud | `"AZUREPUBLICCLOUD"` (default value), `"AZURECHINACLOUD"`, `"AZUREUSGOVERNMENTCLOUD"`, `"AZUREGERMANCLOUD"` |
|
||||
|
||||
Additionally, you must provide the authentication fields as explained in the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
|
||||
|
||||
### Kubernetes
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|----------------|:--------:|---------|---------|
|
||||
| vaultName | Y | The name of the Azure Key Vault | `"mykeyvault"`
|
||||
| spnTenantId | Y | Service Principal Tenant Id | `"spnTenantId"`
|
||||
| spnClientId | Y | Service Principal App Id | `"spnAppId"`
|
||||
| spnCertificate | Y | PKCS 12 encoded bytes of the certificate. See [configure the component](#configure-the-component) for details on encoding this in a Kubernetes secret. | `secretKeyRef: ...` <br /> See [configure the component](#configure-the-component) for more information.
|
||||
|
||||
|
||||
## Setup Key Vault and service principal
|
||||
## Create the Azure Key Vault and authorize the Service Principal
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Azure Subscription](https://azure.microsoft.com/en-us/free/)
|
||||
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
|
||||
- [Azure Subscription](https://azure.microsoft.com/free/)
|
||||
- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
|
||||
- [jq](https://stedolan.github.io/jq/download/)
|
||||
- The scripts below are optimized for a bash or zsh shell
|
||||
|
||||
Make sure you have followed the steps in the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document to create an Azure AD application (also called Service Principal). You will need the following values:
|
||||
|
||||
- `SERVICE_PRINCIPAL_ID`: the ID of the Service Principal that you created for a given application
|
||||
|
||||
### Steps
|
||||
|
||||
1. Login to Azure and set the default subscription
|
||||
1. Set a variable with the Service Principal that you created:
|
||||
|
||||
```bash
|
||||
# Log in Azure
|
||||
az login
|
||||
```sh
|
||||
SERVICE_PRINCIPAL_ID="[your_service_principal_object_id]"
|
||||
```
|
||||
|
||||
# Set your subscription to the default subscription
|
||||
az account set -s [your subscription id]
|
||||
```
|
||||
2. Set a variable with the location where to create all resources:
|
||||
|
||||
2. Create an Azure Key Vault in a region
|
||||
```sh
|
||||
LOCATION="[your_location]"
|
||||
```
|
||||
|
||||
```bash
|
||||
az keyvault create --location [region] --name [your_keyvault] --resource-group [your resource group]
|
||||
```
|
||||
(You can get the full list of options with: `az account list-locations --output tsv`)
|
||||
|
||||
3. Create a service principal
|
||||
3. Create a Resource Group, giving it any name you'd like:
|
||||
|
||||
Create a service principal with a new certificate and store the 1-year certificate inside your keyvault's certificate vault. You can skip this step if you want to use an existing service principal for keyvault instead of creating new one
|
||||
```sh
|
||||
RG_NAME="[resource_group_name]"
|
||||
RG_ID=$(az group create \
|
||||
--name "${RG_NAME}" \
|
||||
--location "${LOCATION}" \
|
||||
| jq -r .id)
|
||||
```
|
||||
|
||||
```bash
|
||||
az ad sp create-for-rbac --name [your_service_principal_name] --create-cert --cert [certificate_name] --keyvault [your_keyvault] --skip-assignment --years 1
|
||||
4. Create an Azure Key Vault (that uses Azure RBAC for authorization):
|
||||
|
||||
{
|
||||
"appId": "a4f90000-0000-0000-0000-00000011d000",
|
||||
"displayName": "[your_service_principal_name]",
|
||||
"name": "http://[your_service_principal_name]",
|
||||
"password": null,
|
||||
"tenant": "34f90000-0000-0000-0000-00000011d000"
|
||||
}
|
||||
```
|
||||
```sh
|
||||
KEYVAULT_NAME="[key_vault_name]"
|
||||
az keyvault create \
|
||||
--name "${KEYVAULT_NAME}" \
|
||||
--enable-rbac-authorization true \
|
||||
--resource-group "${RG_NAME}" \
|
||||
--location "${LOCATION}"
|
||||
```
|
||||
|
||||
**Save both the appId and tenant from the output which will be used in the next step**
|
||||
5. Using RBAC, assign a role to the Azure AD application so it can access the Key Vault.
|
||||
In this case, assign the "Key Vault Crypto Officer" role, which has broad access; other more restrictive roles can be used as well, depending on your application.
|
||||
|
||||
4. Get the Object Id for [your_service_principal_name]
|
||||
|
||||
```bash
|
||||
az ad sp show --id [service_principal_app_id]
|
||||
|
||||
{
|
||||
...
|
||||
"objectId": "[your_service_principal_object_id]",
|
||||
"objectType": "ServicePrincipal",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
5. Grant the service principal the GET permission to your Azure Key Vault
|
||||
|
||||
```bash
|
||||
az keyvault set-policy --name [your_keyvault] --object-id [your_service_principal_object_id] --secret-permissions get
|
||||
```
|
||||
|
||||
Now that your service principal has access to your keyvault you are ready to configure the secret store component to use secrets stored in your keyvault to access other components securely.
|
||||
|
||||
6. Download the certificate in PFX format from your Azure Key Vault either using the Azure portal or the Azure CLI:
|
||||
|
||||
- **Using the Azure portal:**
|
||||
|
||||
Go to your key vault on the Azure portal and navigate to the *Certificates* tab under *Settings*. Find the certificate that was created during the service principal creation, named [certificate_name] and click on it.
|
||||
|
||||
Click *Download in PFX/PEM format* to download the certificate.
|
||||
|
||||
- **Using the Azure CLI:**
|
||||
|
||||
```bash
|
||||
az keyvault secret download --vault-name [your_keyvault] --name [certificate_name] --encoding base64 --file [certificate_name].pfx
|
||||
```
|
||||
```sh
|
||||
az role assignment create \
|
||||
--assignee "${SERVICE_PRINCIPAL_ID}" \
|
||||
--role "Key Vault Crypto Officer" \
|
||||
--scope "${RG_ID}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}"
|
||||
```
|
||||
|
||||
## Configure the component
|
||||
|
||||
{{< tabs "Self-Hosted" "Kubernetes">}}
|
||||
|
||||
{{% codetab %}}
|
||||
1. Copy downloaded PFX cert from your Azure Keyvault into your components directory or a secure location on your local disk
|
||||
|
||||
2. Create a file called `azurekeyvault.yaml` in the components directory
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: [your_keyvault_name]
|
||||
- name: spnTenantId
|
||||
value: "[your_service_principal_tenant_id]"
|
||||
- name: spnClientId
|
||||
value: "[your_service_principal_app_id]"
|
||||
- name: spnCertificateFile
|
||||
value : "[pfx_certificate_file_fully_qualified_local_path]"
|
||||
```
|
||||
|
||||
Fill in the metadata fields with your Key Vault details from the above setup process.
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
In Kubernetes, you store the certificate for the service principal into the Kubernetes Secret Store and then enable Azure Key Vault secret store with this certificate in Kubernetes secretstore.
|
||||
|
||||
1. Create a kubernetes secret using the following command:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic [your_k8s_spn_secret_name] --from-file=[your_k8s_spn_secret_key]=[pfx_certificate_file_fully_qualified_local_path]
|
||||
```
|
||||
|
||||
- `[pfx_certificate_file_fully_qualified_local_path]` is the path of PFX cert file you downloaded above
|
||||
- `[your_k8s_spn_secret_name]` is secret name in Kubernetes secret store
|
||||
- `[your_k8s_spn_secret_key]` is secret key in Kubernetes secret store
|
||||
|
||||
2. Create a `azurekeyvault.yaml` component file
|
||||
|
||||
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the certificate stored in Kubernetes secret store.
|
||||
To use a **client secret**, create a file called `azurekeyvault.yaml` in the components directory, filling in with the Azure AD application that you created following the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document:
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
|
@ -201,32 +130,142 @@ spec:
|
|||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: [your_keyvault_name]
|
||||
- name: spnTenantId
|
||||
value: "[your_service_principal_tenant_id]"
|
||||
- name: spnClientId
|
||||
value: "[your_service_principal_app_id]"
|
||||
- name: spnCertificate
|
||||
secretKeyRef:
|
||||
name: [your_k8s_spn_secret_name]
|
||||
key: [your_k8s_spn_secret_key]
|
||||
auth:
|
||||
secretStore: kubernetes
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureClientSecret
|
||||
value : "[your_client_secret]"
|
||||
```
|
||||
|
||||
3. Apply `azurekeyvault.yaml` component
|
||||
If you want to use a **certificate** saved on the local disk, instead, use this template, filling in with details of the Azure AD application that you created following the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document:
|
||||
|
||||
```bash
|
||||
kubectl apply -f azurekeyvault.yaml
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureCertificateFile
|
||||
value : "[pfx_certificate_file_fully_qualified_local_path]"
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
In Kubernetes, you store the client secret or the certificate into the Kubernetes Secret Store and then refer to those in the YAML file. You will need the details of the Azure AD application that was created following the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
|
||||
|
||||
To use a **client secret**:
|
||||
|
||||
1. Create a Kubernetes secret using the following command:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic [your_k8s_secret_name] --from-literal=[your_k8s_secret_key]=[your_client_secret]
|
||||
```
|
||||
|
||||
- `[your_client_secret]` is the application's client secret as generated above
|
||||
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
|
||||
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
|
||||
|
||||
|
||||
2. Create an `azurekeyvault.yaml` component file.
|
||||
|
||||
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the client secret stored in the Kubernetes secret store.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureClientSecret
|
||||
secretKeyRef:
|
||||
name: "[your_k8s_secret_name]"
|
||||
key: "[your_k8s_secret_key]"
|
||||
auth:
|
||||
secretStore: kubernetes
|
||||
```
|
||||
|
||||
3. Apply the `azurekeyvault.yaml` component:
|
||||
|
||||
```bash
|
||||
kubectl apply -f azurekeyvault.yaml
|
||||
```
|
||||
|
||||
To use a **certificate**:
|
||||
|
||||
1. Create a Kubernetes secret using the following command:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic [your_k8s_secret_name] --from-file=[your_k8s_secret_key]=[pfx_certificate_file_fully_qualified_local_path]
|
||||
```
|
||||
|
||||
- `[pfx_certificate_file_fully_qualified_local_path]` is the path of PFX file you obtained earlier
|
||||
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
|
||||
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
|
||||
|
||||
2. Create an `azurekeyvault.yaml` component file.
|
||||
|
||||
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the certificate stored in the Kubernetes secret store.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: azurekeyvault
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.azure.keyvault
|
||||
version: v1
|
||||
metadata:
|
||||
- name: vaultName
|
||||
value: "[your_keyvault_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureCertificate
|
||||
secretKeyRef:
|
||||
name: "[your_k8s_secret_name]"
|
||||
key: "[your_k8s_secret_key]"
|
||||
auth:
|
||||
secretStore: kubernetes
|
||||
```
|
||||
|
||||
3. Apply the `azurekeyvault.yaml` component:
|
||||
|
||||
```bash
|
||||
kubectl apply -f azurekeyvault.yaml
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
## References
|
||||
|
||||
- [Azure CLI Keyvault CLI](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)
|
||||
- [Create an Azure service principal with Azure CLI](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest)
|
||||
- [Authenticating to Azure]({{< ref authenticating-azure.md >}})
|
||||
- [Azure CLI: keyvault commands](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)
|
||||
- [Secrets building block]({{< ref secrets >}})
|
||||
- [How-To: Retrieve a secret]({{< ref "howto-secrets.md" >}})
|
||||
- [How-To: Reference secrets in Dapr components]({{< ref component-secrets.md >}})
|
||||
|
|
|
@ -31,6 +31,8 @@ spec:
|
|||
value: [path to the JSON file]
|
||||
- name: nestedSeparator
|
||||
value: ":"
|
||||
- name: multiValued
|
||||
value: "false"
|
||||
```
|
||||
|
||||
## Spec metadata fields
|
||||
|
@ -38,11 +40,12 @@ spec:
|
|||
| Field | Required | Details | Example |
|
||||
|--------------------|:--------:|-------------------------------------------------------------------------|--------------------------|
|
||||
| secretsFile | Y | The path to the file where secrets are stored | `"path/to/file.json"` |
|
||||
| nestedSeparator | N | Used by the store when flattening the JSON hierarchy to a map. Defaults to `":"` | `":"` |
|
||||
| nestedSeparator | N | Used by the store when flattening the JSON hierarchy to a map. Defaults to `":"` | `":"`
|
||||
| multiValued | N | Allows one level of multi-valued key/value pairs before flattening JSON hierarchy. Defaults to `"false"` | `"true"` |
|
||||
|
||||
## Setup JSON file to hold the secrets
|
||||
|
||||
Given the following json:
|
||||
Given the following JSON loaded from `secretsFile`:
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -54,7 +57,7 @@ Given the following json:
|
|||
}
|
||||
```
|
||||
|
||||
The store will load the file and create a map with the following key value pairs:
|
||||
If `multiValued` is `"false"`, the store will load the file and create a map with the following key value pairs:
|
||||
|
||||
| flattened key | value |
|
||||
| --- | --- |
|
||||
|
@ -62,7 +65,49 @@ The store will load the file and create a map with the following key value pairs
|
|||
|"connectionStrings:sql" | "your sql connection string" |
|
||||
|"connectionStrings:mysql"| "your mysql connection string" |
|
||||
|
||||
Use the flattened key (`connectionStrings:sql`) to access the secret.
|
||||
Use the flattened key (`connectionStrings:sql`) to access the secret. The following JSON map returned:
|
||||
|
||||
```json
|
||||
{
|
||||
"connectionStrings:sql": "your sql connection string"
|
||||
}
|
||||
```
|
||||
|
||||
If `multiValued` is `"true"`, you would instead use the top level key. In this example, `connectionStrings` would return the following map:
|
||||
|
||||
```json
|
||||
{
|
||||
"sql": "your sql connection string",
|
||||
"mysql": "your mysql connection string"
|
||||
}
|
||||
```
|
||||
|
||||
Nested structures after the top level will be flattened. In this example, `connectionStrings` would return the following map:
|
||||
|
||||
JSON from `secretsFile`:
|
||||
|
||||
```json
|
||||
{
|
||||
"redisPassword": "your redis password",
|
||||
"connectionStrings": {
|
||||
"mysql": {
|
||||
"username": "your mysql username",
|
||||
"password": "your mysql password"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"mysql:username": "your mysql username",
|
||||
"mysql:password": "your mysql password"
|
||||
}
|
||||
```
|
||||
|
||||
This is useful in order to mimic secret stores like Vault or Kubernetes that return multiple key/value pairs per secret key.
|
||||
|
||||
## Related links
|
||||
- [Secrets building block]({{< ref secrets >}})
|
||||
|
|
|
@ -9,8 +9,7 @@ aliases:
|
|||
|
||||
## Component format
|
||||
|
||||
To setup Azure Blobstorage state store create a component of type `state.azure.blobstorage`. See [this guide]({{< ref "howto-get-save-state.md#step-1-setup-a-state-store" >}}) on how to create and apply a state store configuration.
|
||||
|
||||
To setup the Azure Blob Storage state store create a component of type `state.azure.blobstorage`. See [this guide]({{< ref "howto-get-save-state.md#step-1-setup-a-state-store" >}}) on how to create and apply a state store configuration.
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
|
@ -23,42 +22,105 @@ spec:
|
|||
version: v1
|
||||
metadata:
|
||||
- name: accountName
|
||||
value: <REPLACE-WITH-ACCOUNT-NAME>
|
||||
value: "[your_account_name]"
|
||||
- name: accountKey
|
||||
value: <REPLACE-WITH-ACCOUNT-KEY>
|
||||
value: "[your_account_key]"
|
||||
- name: containerName
|
||||
value: <REPLACE-WITH-CONTAINER-NAME>
|
||||
value: "[your_container_name]"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|--------------------|:--------:|---------|---------|
|
||||
| accountName | Y | The storage account name | `"mystorageaccount"`.
|
||||
| accountKey | Y | Primary or secondary storage key | `"key"`
|
||||
| accountKey | Y (unless using Azure AD) | Primary or secondary storage key | `"key"`
|
||||
| containerName | Y | The name of the container to be used for Dapr state. The container will be created for you if it doesn't exist | `"container"`
|
||||
| ContentType | N | The blob’s content type | `"text/plain"`
|
||||
| `azureEnvironment` | N | Optional name for the Azure environment if using a different Azure cloud | `"AZUREPUBLICCLOUD"` (default value), `"AZURECHINACLOUD"`, `"AZUREUSGOVERNMENTCLOUD"`, `"AZUREGERMANCLOUD"`
|
||||
| ContentType | N | The blob's content type | `"text/plain"`
|
||||
| ContentMD5 | N | The blob's MD5 hash | `"vZGKbMRDAnMs4BIwlXaRvQ=="`
|
||||
| ContentEncoding | N | The blob's content encoding | `"UTF-8"`
|
||||
| ContentLanguage | N | The blob's content language | `"en-us"`
|
||||
| ContentDisposition | N | The blob's content disposition. Conveys additional information about how to process the response payload | `"attachment"`
|
||||
| CacheControl | N | The blob's cache control | `"no-cache"`
|
||||
|
||||
## Setup Azure Blobstorage
|
||||
## Setup Azure Blob Storage
|
||||
|
||||
[Follow the instructions](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-create?tabs=azure-portal) from the Azure documentation on how to create an Azure Storage Account.
|
||||
|
||||
If you wish to create a container for Dapr to use, you can do so beforehand. However, Blob Storage state provider will create one for you automatically if it doesn't exist.
|
||||
If you wish to create a container for Dapr to use, you can do so beforehand. However, the Blob Storage state provider will create one for you automatically if it doesn't exist.
|
||||
|
||||
In order to setup Azure Blob Storage as a state store, you will need the following properties:
|
||||
- **AccountName**: The storage account name. For example: **mystorageaccount**.
|
||||
- **AccountKey**: Primary or secondary storage key.
|
||||
- **ContainerName**: The name of the container to be used for Dapr state. The container will be created for you if it doesn't exist.
|
||||
|
||||
- **accountName**: The storage account name. For example: **mystorageaccount**.
|
||||
- **accountKey**: Primary or secondary storage account key.
|
||||
- **containerName**: The name of the container to be used for Dapr state. The container will be created for you if it doesn't exist.
|
||||
|
||||
### Authenticating with Azure AD
|
||||
|
||||
This component supports authentication with Azure AD as an alternative to use account keys. Whenever possible, it is recommended that you use Azure AD for authentication in production systems, to take advantage of better security, fine-tuned access control, and the ability to use managed identities for apps running on Azure.
|
||||
|
||||
> The following scripts are optimized for a bash or zsh shell and require the following apps installed:
|
||||
>
|
||||
> - [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
|
||||
> - [jq](https://stedolan.github.io/jq/download/)
|
||||
>
|
||||
> You must also be authenticated with Azure in your Azure CLI.
|
||||
|
||||
1. To get started with using Azure AD for authenticating the Blob Storage state store component, make sure you've created an Azure AD application and a Service Principal as explained in the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
|
||||
Once done, set a variable with the ID of the Service Principal that you created:
|
||||
|
||||
```sh
|
||||
SERVICE_PRINCIPAL_ID="[your_service_principal_object_id]"
|
||||
```
|
||||
|
||||
2. Set the following variables with the name of your Azure Storage Account and the name of the Resource Group where it's located:
|
||||
|
||||
```sh
|
||||
STORAGE_ACCOUNT_NAME="[your_storage_account_name]"
|
||||
RG_NAME="[your_resource_group_name]"
|
||||
```
|
||||
|
||||
3. Using RBAC, assign a role to our Service Principal so it can access data inside the Storage Account.
|
||||
In this case, you are assigning the "Storage blob Data Contributor" role, which has broad access; other more restrictive roles can be used as well, depending on your application.
|
||||
|
||||
```sh
|
||||
RG_ID=$(az group show --resource-group ${RG_NAME} | jq -r ".id")
|
||||
az role assignment create \
|
||||
--assignee "${SERVICE_PRINCIPAL_ID}" \
|
||||
--role "Storage blob Data Contributor" \
|
||||
--scope "${RG_ID}/providers/Microsoft.Storage/storageAccounts/${STORAGE_ACCOUNT_NAME}"
|
||||
```
|
||||
|
||||
When authenticating your component using Azure AD, the `accountKey` field is not required. Instead, please specify the required credentials in the component's metadata (if any) according to the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: <NAME>
|
||||
namespace: <NAMESPACE>
|
||||
spec:
|
||||
type: state.azure.blobstorage
|
||||
version: v1
|
||||
metadata:
|
||||
- name: accountName
|
||||
value: "[your_account_name]"
|
||||
- name: containerName
|
||||
value: "[your_container_name]"
|
||||
- name: azureTenantId
|
||||
value: "[your_tenant_id]"
|
||||
- name: azureClientId
|
||||
value: "[your_client_id]"
|
||||
- name: azureClientSecret
|
||||
value : "[your_client_secret]"
|
||||
```
|
||||
|
||||
## Apply the configuration
|
||||
|
||||
|
@ -66,16 +128,17 @@ In order to setup Azure Blob Storage as a state store, you will need the followi
|
|||
|
||||
To apply Azure Blob Storage state store to Kubernetes, use the `kubectl` CLI:
|
||||
|
||||
```
|
||||
```sh
|
||||
kubectl apply -f azureblob.yaml
|
||||
```
|
||||
|
||||
### Running locally
|
||||
|
||||
To run locally, create a `components` dir containing the YAML file and provide the path to the `dapr run` command with the flag `--components-path`.
|
||||
|
||||
This state store creates a blob file in the container and puts raw state inside it.
|
||||
|
||||
For example, the following operation coming from service called `myservice`
|
||||
For example, the following operation coming from service called `myservice`:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3500/v1.0/state \
|
||||
|
@ -88,13 +151,14 @@ curl -X POST http://localhost:3500/v1.0/state \
|
|||
]'
|
||||
```
|
||||
|
||||
creates the blob file in the containter with `key` as filename and `value` as the contents of file.
|
||||
This creates the blob file in the container with `key` as filename and `value` as the contents of file.
|
||||
|
||||
## Concurrency
|
||||
|
||||
Azure Blob Storage state concurrency is achieved by using `ETag`s according to [the Azure Blob Storage documentation](https://docs.microsoft.com/en-us/azure/storage/common/storage-concurrency#managing-concurrency-in-blob-storage).
|
||||
|
||||
## Related links
|
||||
|
||||
- [Basic schema for a Dapr component]({{< ref component-schema >}})
|
||||
- Read [this guide]({{< ref "howto-get-save-state.md#step-2-save-and-retrieve-a-single-state" >}}) for instructions on configuring state store components
|
||||
- [State management building block]({{< ref state-management >}})
|
||||
|
|
|
@ -39,6 +39,10 @@ spec:
|
|||
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
## Primary Key
|
||||
|
||||
In order to use DynamoDB as a Dapr state store, the table must have a primary key named `key`.
|
||||
|
||||
## Spec metadata fields
|
||||
|
||||
| Field | Required | Details | Example |
|
||||
|
|
|
@ -35,6 +35,8 @@ spec:
|
|||
value: # Optional
|
||||
- name: maxRetryBackoff
|
||||
value: # Optional
|
||||
- name: ttlInSeconds
|
||||
value: <int> # Optional
|
||||
```
|
||||
**TLS:** If the Redis instance supports TLS with public certificates it can be configured to enable or disable TLS `true` or `false`.
|
||||
|
||||
|
@ -58,6 +60,7 @@ If you wish to use Redis as an actor store, append the following to the yaml.
|
|||
|--------------------|:--------:|---------|---------|
|
||||
| redisHost | Y | Connection-string for the redis host | `localhost:6379`, `redis-master.default.svc.cluster.local:6379`
|
||||
| redisPassword | Y | Password for Redis host. No Default. Can be `secretKeyRef` to use a secret reference | `""`, `"KeFg23!"`
|
||||
| redisUsername | N | Username for Redis host. Defaults to empty. Make sure your redis server version is 6 or above, and have created acl rule correctly. | `""`, `"default"`
|
||||
| consumerID | N | The consumer group ID | `"myGroup"`
|
||||
| enableTLS | N | If the Redis instance supports TLS with public certificates, can be configured to be enabled or disabled. Defaults to `"false"` | `"true"`, `"false"`
|
||||
| maxRetries | N | Maximum number of retries before giving up. Defaults to `3` | `5`, `10`
|
||||
|
@ -81,6 +84,7 @@ If you wish to use Redis as an actor store, append the following to the yaml.
|
|||
| idleCheckFrequency | N | Frequency of idle checks made by idle connections reaper. Default is `"1m"`. `"-1"` disables idle connections reaper. | `"-1"`
|
||||
| idleTimeout | N | Amount of time after which the client closes idle connections. Should be less than server's timeout. Default is `"5m"`. `"-1"` disables idle timeout check. | `"10m"`
|
||||
| actorStateStore | N | Consider this state store for actors. Defaults to `"false"` | `"true"`, `"false"`
|
||||
| ttlInSeconds | N | Allows specifying a default Time-to-live (TTL) in seconds that will be applied to every state store request unless TTL is explicitly defined via the [request metadata]({{< ref "state-store-ttl.md" >}}). | `600`
|
||||
|
||||
## Setup Redis
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ spec:
|
|||
- name: connectionString
|
||||
value: <REPLACE-WITH-CONNECTION-STRING> # Required.
|
||||
- name: tableName
|
||||
value: <REPLACE-WITH-TABLE-NAME> # Required.
|
||||
value: <REPLACE-WITH-TABLE-NAME> # Optional. defaults to "state"
|
||||
- name: keyType
|
||||
value: <REPLACE-WITH-KEY-TYPE> # Optional. defaults to "string"
|
||||
- name: keyLength
|
||||
|
@ -41,7 +41,7 @@ spec:
|
|||
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
If you wish to use Redis as an [actor state store]({{< ref "state_api.md#configuring-state-store-for-actors" >}}), append the following to the yaml.
|
||||
If you wish to use SQL server as an [actor state store]({{< ref "state_api.md#configuring-state-store-for-actors" >}}), append the following to the yaml.
|
||||
|
||||
```yaml
|
||||
- name: actorStateStore
|
||||
|
@ -52,8 +52,8 @@ If you wish to use Redis as an [actor state store]({{< ref "state_api.md#configu
|
|||
|
||||
| Field | Required | Details | Example |
|
||||
|--------------------|:--------:|---------|---------|
|
||||
| connectionString | Y | The connection string used to connect | `"Server=myServerName\myInstanceName;Database=myDataBase;User Id=myUsername;Password=myPassword;"`
|
||||
| tableName | Y | The name of the table to use. Alpha-numeric with underscores | `"table_name"`
|
||||
| connectionString | Y | The connection string used to connect. If the connection string contains the database it must already exist. If the database is omitted a default database named `"Dapr"` is created. | `"Server=myServerName\myInstanceName;Database=myDataBase;User Id=myUsername;Password=myPassword;"`
|
||||
| tableName | N | The name of the table to use. Alpha-numeric with underscores. Defaults to `"state"` | `"table_name"`
|
||||
| keyType | N | The type of key used. Defaults to `"string"` | `"string"`
|
||||
| keyLength | N | The max length of key. Used along with `"string"` keytype. Defaults to `"200"` | `"200"`
|
||||
| schema | N | The schema to use. Defaults to `"dbo"` | `"dapr"`,`"dbo"`
|
||||
|
@ -69,7 +69,7 @@ If you wish to use Redis as an [actor state store]({{< ref "state_api.md#configu
|
|||
|
||||
In order to setup SQL Server as a state store, you need the following properties:
|
||||
|
||||
- **Connection String**: the SQL Server connection string. For example: server=localhost;user id=sa;password=your-password;port=1433;database=mydatabase;
|
||||
- **Connection String**: The SQL Server connection string. For example: server=localhost;user id=sa;password=your-password;port=1433;database=mydatabase;
|
||||
- **Schema**: The database schema to use (default=dbo). Will be created if does not exist
|
||||
- **Table Name**: The database table name. Will be created if does not exist
|
||||
- **Indexed Properties**: Optional properties from json data which will be indexed and persisted as individual column
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<style>
|
||||
.feedback--title {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
.feedback--answer {
|
||||
display: inline-block;
|
||||
}
|
||||
.feedback--answer-no {
|
||||
margin-left: 1em;
|
||||
}
|
||||
.feedback--response {
|
||||
display: none;
|
||||
margin-top: 1em;
|
||||
}
|
||||
.feedback--response__visible {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<div class="d-print-none">
|
||||
<h2 class="feedback--title">Feedback</h2>
|
||||
<p class="feedback--question">Was this page helpful?</p>
|
||||
<button class="btn btn-primary mb-4 feedback--answer feedback--answer-yes">Yes</button>
|
||||
<button class="btn btn-primary mb-4 feedback--answer feedback--answer-no">No</button>
|
||||
<p class="feedback--response feedback--response-yes">
|
||||
{{ .yes | safeHTML }}
|
||||
</p>
|
||||
<p class="feedback--response feedback--response-no">
|
||||
{{ .no | safeHTML }}
|
||||
</p>
|
||||
</div>
|
||||
<script>
|
||||
const yesButton = document.querySelector('.feedback--answer-yes');
|
||||
const noButton = document.querySelector('.feedback--answer-no');
|
||||
const yesResponse = document.querySelector('.feedback--response-yes');
|
||||
const noResponse = document.querySelector('.feedback--response-no');
|
||||
const disableButtons = () => {
|
||||
yesButton.disabled = true;
|
||||
noButton.disabled = true;
|
||||
};
|
||||
const sendFeedback = (value) => {
|
||||
if (typeof ga !== 'function') return;
|
||||
const args = {
|
||||
command: 'send',
|
||||
hitType: 'event',
|
||||
category: 'Helpful',
|
||||
action: 'click',
|
||||
label: window.location.pathname,
|
||||
value: value
|
||||
};
|
||||
ga(args.command, args.hitType, args.category, args.action, args.label, args.value);
|
||||
};
|
||||
yesButton.addEventListener('click', () => {
|
||||
yesResponse.classList.add('feedback--response__visible');
|
||||
disableButtons();
|
||||
sendFeedback(1);
|
||||
});
|
||||
noButton.addEventListener('click', () => {
|
||||
noResponse.classList.add('feedback--response__visible');
|
||||
disableButtons();
|
||||
sendFeedback(0);
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1 @@
|
|||
{{- if .Get "short" }}1.4{{ else if .Get "long" }}1.4.3{{ else if .Get "cli" }}1.4.0{{ else }}1.4.3{{ end -}}
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"globalHeaders": {
|
||||
"X-Frame-Options": "DENY"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 1e23f32eafdebe571db6e19717cf5317f09a5402
|
Loading…
Reference in New Issue