From 90691593890cfd0e63e591671ff527cc8dfc67bd Mon Sep 17 00:00:00 2001 From: Elena Kolevska Date: Thu, 31 Oct 2024 17:46:16 +0000 Subject: [PATCH 01/31] Updates docs for circuit breaker Signed-off-by: Elena Kolevska --- daprdocs/content/en/operations/resiliency/policies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/resiliency/policies.md b/daprdocs/content/en/operations/resiliency/policies.md index 086ca7fd5d0..73e225167e4 100644 --- a/daprdocs/content/en/operations/resiliency/policies.md +++ b/daprdocs/content/en/operations/resiliency/policies.md @@ -88,7 +88,7 @@ Circuit Breaker (CB) policies are used when other applications/services/componen | `maxRequests` | The maximum number of requests allowed to pass through when the CB is half-open (recovering from failure). Defaults to `1`. | | `interval` | The cyclical period of time used by the CB to clear its internal counts. If set to 0 seconds, this never clears. Defaults to `0s`. | | `timeout` | The period of the open state (directly after failure) until the CB switches to half-open. Defaults to `60s`. | -| `trip` | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) statement that is evaluated by the CB. When the statement evaluates to true, the CB trips and becomes open. Defaults to `consecutiveFailures > 5`. | +| `trip` | A [Common Expression Language (CEL)](https://github.com/google/cel-spec) statement that is evaluated by the CB. When the statement evaluates to true, the CB trips and becomes open. Defaults to `consecutiveFailures > 5`. Other possible values are `requests` and `totalFailures` where `requests` represents the number of either successful or failed calls before the circuit opens and `totalFailures` represents the total (not necessarily consecutive) number of failed attempts before the circuit opens. Example: `requests > 5` and `totalFailures >3`.| Example: From 125eb19c9aed78e7838f0aa05e3f1242b144d804 Mon Sep 17 00:00:00 2001 From: Jake Engelberg Date: Wed, 6 Nov 2024 18:20:23 -0500 Subject: [PATCH 02/31] add exhaustive list of error codes and description of metric flag Signed-off-by: Jake Engelberg --- .../observability/metrics/metrics-overview.md | 16 ++ .../content/en/reference/api/error_codes.md | 173 ++++++++++++++---- 2 files changed, 156 insertions(+), 33 deletions(-) diff --git a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md index 5f07bb325f9..deb7882cb25 100644 --- a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md +++ b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md @@ -70,6 +70,22 @@ spec: enabled: false ``` +## Configuring metrics for error codes + +You can enable additional metrics for [Dapr API error codes](https://github.com/dapr/dapr/blob/master/docs/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. See the specific metrics described in the [Dapr development docs](https://github.com/dapr/dapr/blob/master/docs/development/dapr-metrics.md). + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Configuration +metadata: + name: tracing + namespace: default +spec: + metrics: + enabled: true + recordErrorCodes: true +``` + ## Optimizing HTTP metrics reporting with path matching When invoking Dapr using HTTP, metrics are created for each requested method by default. This can result in a high number of metrics, known as high cardinality, which can impact memory usage and CPU. diff --git a/daprdocs/content/en/reference/api/error_codes.md b/daprdocs/content/en/reference/api/error_codes.md index 19d3b8cc36c..2e18882aa07 100644 --- a/daprdocs/content/en/reference/api/error_codes.md +++ b/daprdocs/content/en/reference/api/error_codes.md @@ -7,6 +7,7 @@ weight: 1400 --- For http calls made to Dapr runtime, when an error is encountered, an error json is returned in http response body. The json contains an error code and an descriptive error message, e.g. + ``` { "errorCode": "ERR_STATE_GET", @@ -14,36 +15,142 @@ For http calls made to Dapr runtime, when an error is encountered, an error json } ``` -Following table lists the error codes returned by Dapr runtime: - -| Error Code | Description | -|-----------------------------------|-------------| -| ERR_ACTOR_INSTANCE_MISSING | Error getting an actor instance. This means that actor is now hosted in some other service replica. -| ERR_ACTOR_RUNTIME_NOT_FOUND | Error getting the actor instance. -| ERR_ACTOR_REMINDER_CREATE | Error creating a reminder for an actor. -| ERR_ACTOR_REMINDER_DELETE | Error deleting a reminder for an actor. -| ERR_ACTOR_TIMER_CREATE | Error creating a timer for an actor. -| ERR_ACTOR_TIMER_DELETE | Error deleting a timer for an actor. -| ERR_ACTOR_REMINDER_GET | Error getting a reminder for an actor. -| ERR_ACTOR_INVOKE_METHOD | Error invoking a method on an actor. -| ERR_ACTOR_STATE_DELETE | Error deleting the state for an actor. -| ERR_ACTOR_STATE_GET | Error getting the state for an actor. -| ERR_ACTOR_STATE_TRANSACTION_SAVE | Error storing actor state transactionally. -| ERR_PUBSUB_NOT_FOUND | Error referencing the Pub/Sub component in Dapr runtime. -| ERR_PUBSUB_PUBLISH_MESSAGE | Error publishing a message. -| ERR_PUBSUB_FORBIDDEN | Error message forbidden by access controls. -| ERR_PUBSUB_CLOUD_EVENTS_SER | Error serializing Pub/Sub event envelope. -| ERR_STATE_STORE_NOT_FOUND | Error referencing a state store not found. -| ERR_STATE_STORES_NOT_CONFIGURED | Error no state stores configured. -| ERR_NOT_SUPPORTED_STATE_OPERATION | Error transaction requested on a state store with no transaction support. -| ERR_STATE_GET | Error getting a state for state store. -| ERR_STATE_DELETE | Error deleting a state from state store. -| ERR_STATE_SAVE | Error saving a state in state store. -| ERR_INVOKE_OUTPUT_BINDING | Error invoking an output binding. -| ERR_MALFORMED_REQUEST | Error with a malformed request. -| ERR_DIRECT_INVOKE | Error in direct invocation. -| ERR_DESERIALIZE_HTTP_BODY | Error deserializing an HTTP request body. -| ERR_SECRET_STORES_NOT_CONFIGURED | Error that no secret store is configured. -| ERR_SECRET_STORE_NOT_FOUND | Error that specified secret store is not found. -| ERR_HEALTH_NOT_READY | Error that Dapr is not ready. -| ERR_METADATA_GET | Error parsing the Metadata information. +The following tables list the error codes returned by Dapr runtime: + +### Actors (Building Block) + +| Error Code | Description | +| -------------------------------- | ------------------------------------------ | +| ERR_ACTOR_INSTANCE_MISSING | Error when an actor instance is missing. | +| ERR_ACTOR_RUNTIME_NOT_FOUND | Error the actor instance. | +| ERR_ACTOR_REMINDER_CREATE | Error creating a reminder for an actor. | +| ERR_ACTOR_REMINDER_DELETE | Error deleting a reminder for an actor. | +| ERR_ACTOR_TIMER_CREATE | Error creating a timer for an actor. | +| ERR_ACTOR_TIMER_DELETE | Error deleting a timer for an actor. | +| ERR_ACTOR_REMINDER_GET | Error getting a reminder for an actor. | +| ERR_ACTOR_INVOKE_METHOD | Error invoking a method on an actor. | +| ERR_ACTOR_STATE_DELETE | Error deleting the state for an actor. | +| ERR_ACTOR_STATE_GET | Error getting the state for an actor. | +| ERR_ACTOR_STATE_TRANSACTION_SAVE | Error storing actor state transactionally. | +| ERR_ACTOR_REMINDER_NON_HOSTED | Error setting reminder for an actor. | + +### Workflows (Building Block) + +| Error Code | Description | +| -------------------------------- | ----------------------------------------------------------- | +| ERR_GET_WORKFLOW | Error getting workflow. | +| ERR_START_WORKFLOW | Error starting the workflow. | +| ERR_PAUSE_WORKFLOW | Error pausing the workflow. | +| ERR_RESUME_WORKFLOW | Error resuming the workflow. | +| ERR_TERMINATE_WORKFLOW | Error terminating the workflow. | +| ERR_PURGE_WORKFLOW | Error purging workflow. | +| ERR_RAISE_EVENT_WORKFLOW | Error raising an event within the workflow. | +| ERR_WORKFLOW_COMPONENT_MISSING | Error when a workflow component is missing a configuration. | +| ERR_WORKFLOW_COMPONENT_NOT_FOUND | Error when a workflow component is not found. | +| ERR_WORKFLOW_EVENT_NAME_MISSING | Error when the event name for a workflow is missing. | +| ERR_WORKFLOW_NAME_MISSING | Error when the workflow name is missing. | +| ERR_INSTANCE_ID_INVALID | Error invalid workflow instance ID provided. | +| ERR_INSTANCE_ID_NOT_FOUND | Error workflow instance ID not found. | +| ERR_INSTANCE_ID_PROVIDED_MISSING | Error workflow instance ID was provided but missing. | +| ERR_INSTANCE_ID_TOO_LONG | Error workflow instance ID exceeds allowable length. | + +### State Management (Building Block) + +| Error Code | Description | +| ------------------------------------- | ------------------------------------------------------------------------- | +| ERR_STATE_STORE_NOT_FOUND | Error referencing a state store not found. | +| ERR_STATE_STORES_NOT_CONFIGURED | Error no state stores configured. | +| ERR_NOT_SUPPORTED_STATE_OPERATION | Error transaction requested on a state store with no transaction support. | +| ERR_STATE_GET | Error getting a state for state store. | +| ERR_STATE_DELETE | Error deleting a state from state store. | +| ERR_STATE_SAVE | Error saving a state in state store. | +| ERR_STATE_TRANSACTION | Error encountered during state transaction. | +| ERR_STATE_BULK_GET | Error performing bulk retrieval of state entries. | +| ERR_STATE_QUERY | Error querying the state store. | +| ERR_STATE_STORE_NOT_CONFIGURED | Error state store is not configured. | +| ERR_STATE_STORE_NOT_SUPPORTED | Error state store is not supported. | +| ERR_STATE_STORE_TOO_MANY_TRANSACTIONS | Error exceeded maximum allowable transactions. | + +### Configuration (Building Block) + +| Error Code | Description | +| -------------------------------------- | -------------------------------------------- | +| ERR_CONFIGURATION_GET | Error retrieving configuration. | +| ERR_CONFIGURATION_STORE_NOT_CONFIGURED | Error configuration store is not configured. | +| ERR_CONFIGURATION_STORE_NOT_FOUND | Error configuration store not found. | +| ERR_CONFIGURATION_SUBSCRIBE | Error subscribing to a configuration. | +| ERR_CONFIGURATION_UNSUBSCRIBE | Error unsubscribing from a configuration. | + +### Crypto (Building Block) + +| Error Code | Description | +| ----------------------------------- | ------------------------------------------ | +| ERR_CRYPTO | General crypto building block error. | +| ERR_CRYPTO_KEY | Error related to a crypto key. | +| ERR_CRYPTO_PROVIDER_NOT_FOUND | Error specified crypto provider not found. | +| ERR_CRYPTO_PROVIDERS_NOT_CONFIGURED | Error no crypto providers configured. | + +### Secrets (Building Block) + +| Error Code | Description | +| -------------------------------- | ---------------------------------------------------- | +| ERR_SECRET_STORES_NOT_CONFIGURED | Error that no secret store is configured. | +| ERR_SECRET_STORE_NOT_FOUND | Error that specified secret store is not found. | +| ERR_SECRET_GET | Error retrieving the specified secret. | +| ERR_PERMISSION_DENIED | Error access denied due to insufficient permissions. | + +### Pub/Sub (Building Block) + +| Error Code | Description | +| --------------------------- | -------------------------------------------------------- | +| ERR_PUBSUB_NOT_FOUND | Error referencing the Pub/Sub component in Dapr runtime. | +| ERR_PUBSUB_PUBLISH_MESSAGE | Error publishing a message. | +| ERR_PUBSUB_FORBIDDEN | Error message forbidden by access controls. | +| ERR_PUBSUB_CLOUD_EVENTS_SER | Error serializing Pub/Sub event envelope. | +| ERR_PUBSUB_EMPTY | Error empty Pub/Sub. | +| ERR_PUBSUB_NOT_CONFIGURED | Error Pub/Sub component is not configured. | +| ERR_PUBSUB_REQUEST_METADATA | Error with metadata in Pub/Sub request. | +| ERR_PUBSUB_EVENTS_SER | Error serializing Pub/Sub events. | +| ERR_PUBLISH_OUTBOX | Error publishing message to the outbox. | +| ERR_TOPIC_NAME_EMPTY | Error topic name for Pub/Sub message is empty. | + +### Conversation (Building Block) + +| Error Code | Description | +| ------------------------------- | ----------------------------------------------- | +| ERR_INVOKE_OUTPUT_BINDING | Error invoking an output binding. | +| ERR_DIRECT_INVOKE | Error in direct invocation. | +| ERR_CONVERSATION_INVALID_PARMS | Error invalid parameters for conversation. | +| ERR_CONVERSATION_INVOKE | Error invoking the conversation. | +| ERR_CONVERSATION_MISSING_INPUTS | Error missing required inputs for conversation. | +| ERR_CONVERSATION_NOT_FOUND | Error conversation not found. | + +### Distributed Lock (Building Block) + +| Error Code | Description | +| ----------------------------- | ----------------------------------- | +| ERR_TRY_LOCK | Error attempting to acquire a lock. | +| ERR_UNLOCK | Error attempting to release a lock. | +| ERR_LOCK_STORE_NOT_CONFIGURED | Error lock store is not configured. | +| ERR_LOCK_STORE_NOT_FOUND | Error lock store not found. | + +### Healthz + +| Error Code | Description | +| ----------------------------- | --------------------------------------------------------------- | +| ERR_HEALTH_NOT_READY | Error that Dapr is not ready. | +| ERR_HEALTH_APPID_NOT_MATCH | Error the app-id does not match expected value in health check. | +| ERR_OUTBOUND_HEALTH_NOT_READY | Error outbound connection health is not ready. | + +### Common + +| Error Code | Description | +| -------------------------- | ------------------------------------------------ | +| ERR_API_UNIMPLEMENTED | Error API is not implemented. | +| ERR_APP_CHANNEL_NIL | Error application channel is nil. | +| ERR_BAD_REQUEST | Error client request is badly formed or invalid. | +| ERR_BODY_READ | Error reading body. | +| ERR_INTERNAL | Internal server error encountered. | +| ERR_MALFORMED_REQUEST | Error with a malformed request. | +| ERR_MALFORMED_REQUEST_DATA | Error request data is malformed. | +| ERR_MALFORMED_RESPONSE | Error response data is malformed. | From 88a0d66d4424fb78baa6784505ba076a12059a91 Mon Sep 17 00:00:00 2001 From: Jake Engelberg Date: Sun, 1 Dec 2024 15:51:37 -0500 Subject: [PATCH 03/31] match final implementation Signed-off-by: Jake Engelberg --- .../observability/metrics/metrics-overview.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md index deb7882cb25..25d8075e74a 100644 --- a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md +++ b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md @@ -72,8 +72,9 @@ spec: ## Configuring metrics for error codes -You can enable additional metrics for [Dapr API error codes](https://github.com/dapr/dapr/blob/master/docs/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. See the specific metrics described in the [Dapr development docs](https://github.com/dapr/dapr/blob/master/docs/development/dapr-metrics.md). +You can enable additional metrics for [Dapr API error codes](https://github.com/dapr/dapr/blob/master/docs/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. Dapr APIs which communicate back to its caller may return standardized error codes. As described in the [Dapr development docs](https://github.com/dapr/dapr/blob/master/docs/development/dapr-metrics.md), a new metric called `error_code_total` will be recorded, which will allow monitoring of error codes triggered by application, code, and category. See [package errorcodes](https://github.com/dapr/dapr/blob/master/pkg/messages/errorcodes/errorcodes.go) for specific codes and categories. +Example configuration: ```yaml apiVersion: dapr.io/v1alpha1 kind: Configuration @@ -86,6 +87,21 @@ spec: recordErrorCodes: true ``` +Example metric: +```json +{ + app_id="publisher-app", + category="state", + dapr_io_enabled="true", + error_code="ERR_STATE_STORE_NOT_CONFIGURED", + instance="10.244.1.64:9090", + job="kubernetes-service-endpoints", + namespace="my-app", + node="my-node", + service="publisher-app-dapr" +} +``` + ## Optimizing HTTP metrics reporting with path matching When invoking Dapr using HTTP, metrics are created for each requested method by default. This can result in a high number of metrics, known as high cardinality, which can impact memory usage and CPU. From a44a96af104afe65f31518796b32bc28a1368135 Mon Sep 17 00:00:00 2001 From: Jake Engelberg Date: Tue, 3 Dec 2024 11:16:11 -0500 Subject: [PATCH 04/31] fix link, apply suggestion Signed-off-by: Jake Engelberg --- .../observability/metrics/metrics-overview.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md index 25d8075e74a..23fea29e6db 100644 --- a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md +++ b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md @@ -72,7 +72,7 @@ spec: ## Configuring metrics for error codes -You can enable additional metrics for [Dapr API error codes](https://github.com/dapr/dapr/blob/master/docs/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. Dapr APIs which communicate back to its caller may return standardized error codes. As described in the [Dapr development docs](https://github.com/dapr/dapr/blob/master/docs/development/dapr-metrics.md), a new metric called `error_code_total` will be recorded, which will allow monitoring of error codes triggered by application, code, and category. See [package errorcodes](https://github.com/dapr/dapr/blob/master/pkg/messages/errorcodes/errorcodes.go) for specific codes and categories. +You can enable additional metrics for [Dapr API error codes](https://docs.dapr.io/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. Dapr APIs which communicate back to their caller may return standardized error codes. As described in the [Dapr development docs](https://github.com/dapr/dapr/blob/master/docs/development/dapr-metrics.md), a new metric called `error_code_total` is recorded, which allows monitoring of error codes triggered by application, code, and category. See [the `errorcodes` package](https://github.com/dapr/dapr/blob/master/pkg/messages/errorcodes/errorcodes.go) for specific codes and categories. Example configuration: ```yaml @@ -90,15 +90,15 @@ spec: Example metric: ```json { - app_id="publisher-app", - category="state", - dapr_io_enabled="true", - error_code="ERR_STATE_STORE_NOT_CONFIGURED", - instance="10.244.1.64:9090", - job="kubernetes-service-endpoints", - namespace="my-app", - node="my-node", - service="publisher-app-dapr" + "app_id": "publisher-app", + "category": "state", + "dapr_io_enabled": "true", + "error_code": "ERR_STATE_STORE_NOT_CONFIGURED", + "instance": "10.244.1.64:9090", + "job": "kubernetes-service-endpoints", + "namespace": "my-app", + "node": "my-node", + "service": "publisher-app-dapr" } ``` From 411d77de09002afef4e3d5dc118617166f6ea13c Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Tue, 3 Dec 2024 13:56:45 -0500 Subject: [PATCH 05/31] updates for scheduler going stable Signed-off-by: Hannah Hunter --- .../en/concepts/dapr-services/scheduler.md | 2 ++ .../building-blocks/jobs/jobs-overview.md | 2 +- .../support/support-preview-features.md | 3 +-- .../scheduler/scheduler-architecture.png | Bin 38034 -> 148210 bytes 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/concepts/dapr-services/scheduler.md b/daprdocs/content/en/concepts/dapr-services/scheduler.md index 29060fe938e..07050d391dd 100644 --- a/daprdocs/content/en/concepts/dapr-services/scheduler.md +++ b/daprdocs/content/en/concepts/dapr-services/scheduler.md @@ -11,6 +11,8 @@ The diagram below shows how the Scheduler service is used via the jobs API when Diagram showing the Scheduler control plane service and the jobs API +The Scheduler service is deployed by default, including for [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) (actor reminders stored in the Scheduler control plane service as opposed to the Placement control plane service actor reminder system) and workflows. + ## Self-hosted mode The Scheduler service Docker container is started automatically as part of `dapr init`. It can also be run manually as a process if you are running in [slim-init mode]({{< ref self-hosted-no-docker.md >}}). diff --git a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md index 486cfc5d623..4eb98b1e5fb 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md +++ b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md @@ -61,7 +61,7 @@ The Scheduler service enables the scheduling of jobs to scale across multiple re ### Actor reminders -Actors have actor reminders, but present some limitations involving scalability using the Placement service implementation. You can make reminders more scalable by using [`SchedulerReminders`]({{< ref support-preview-features.md >}}). This is set in the configuration for your actor application. +Actors have actor reminders, but present some limitations involving scalability using the Placement service implementation. You can make reminders more scalable by using `SchedulerReminders` in the configuration for your actor application. `SchedulerReminders` defaults to `true`. To disable Scheduler actor reminders, change it to `false`. ## Try out the jobs API diff --git a/daprdocs/content/en/operations/support/support-preview-features.md b/daprdocs/content/en/operations/support/support-preview-features.md index 221b24d8466..9343695656c 100644 --- a/daprdocs/content/en/operations/support/support-preview-features.md +++ b/daprdocs/content/en/operations/support/support-preview-features.md @@ -21,5 +21,4 @@ For CLI there is no explicit opt-in, just the version that this was first made a | **Cryptography** | Encrypt or decrypt data without having to manage secrets keys | N/A | [Cryptography concept]({{< ref "components-concept#cryptography" >}})| v1.11 | | **Actor State TTL** | Allow actors to save records to state stores with Time To Live (TTL) set to automatically clean up old data. In its current implementation, actor state with TTL may not be reflected correctly by clients, read [Actor State Transactions]({{< ref actors_api.md >}}) for more information. | `ActorStateTTL` | [Actor State Transactions]({{< ref actors_api.md >}}) | v1.11 | | **Component Hot Reloading** | Allows for Dapr-loaded components to be "hot reloaded". A component spec is reloaded when it is created/updated/deleted in Kubernetes or on file when running in self-hosted mode. Ignores changes to actor state stores and workflow backends. | `HotReload`| [Hot Reloading]({{< ref components-concept.md >}}) | v1.13 | -| **Subscription Hot Reloading** | Allows for declarative subscriptions to be "hot reloaded". A subscription is reloaded either when it is created/updated/deleted in Kubernetes, or on file in self-hosted mode. In-flight messages are unaffected when reloading. | `HotReload`| [Hot Reloading]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | v1.14 | -| **Scheduler Actor Reminders** | Whilst the [Scheduler service]({{< ref "concepts/dapr-services/scheduler.md" >}}) is deployed by default, Scheduler actor reminders (actor reminders stored in the Scheduler control plane service as opposed to the Placement control plane service actor reminder system) are enabled through a preview feature and needs a feature flag. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) | v1.14 | +| **Subscription Hot Reloading** | Allows for declarative subscriptions to be "hot reloaded". A subscription is reloaded either when it is created/updated/deleted in Kubernetes, or on file in self-hosted mode. In-flight messages are unaffected when reloading. | `HotReload`| [Hot Reloading]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | v1.14 | \ No newline at end of file diff --git a/daprdocs/static/images/scheduler/scheduler-architecture.png b/daprdocs/static/images/scheduler/scheduler-architecture.png index 5cf309bf4a6a79ddf58701270843cd9dba564e32..1b87d1ffd0837da370be5a38f21c92911188a2bc 100644 GIT binary patch literal 148210 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
    {vjdyi}en`Cr{(`Pskpd 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

    r{i5o|z24-< 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%0Def5Ou&g10y`))ycd^zjeeX=tBtL%D(#~k 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 G=l%!f>Ye%k literal 38034 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ȼ$NbbJPiKbJ@&|n?j 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 Date: Wed, 4 Dec 2024 10:34:58 -0500 Subject: [PATCH 06/31] edit 1 - waiting for confirmation Signed-off-by: Hannah Hunter --- .../content/en/operations/support/support-preview-features.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/support/support-preview-features.md b/daprdocs/content/en/operations/support/support-preview-features.md index 9343695656c..a618e47db98 100644 --- a/daprdocs/content/en/operations/support/support-preview-features.md +++ b/daprdocs/content/en/operations/support/support-preview-features.md @@ -21,4 +21,5 @@ For CLI there is no explicit opt-in, just the version that this was first made a | **Cryptography** | Encrypt or decrypt data without having to manage secrets keys | N/A | [Cryptography concept]({{< ref "components-concept#cryptography" >}})| v1.11 | | **Actor State TTL** | Allow actors to save records to state stores with Time To Live (TTL) set to automatically clean up old data. In its current implementation, actor state with TTL may not be reflected correctly by clients, read [Actor State Transactions]({{< ref actors_api.md >}}) for more information. | `ActorStateTTL` | [Actor State Transactions]({{< ref actors_api.md >}}) | v1.11 | | **Component Hot Reloading** | Allows for Dapr-loaded components to be "hot reloaded". A component spec is reloaded when it is created/updated/deleted in Kubernetes or on file when running in self-hosted mode. Ignores changes to actor state stores and workflow backends. | `HotReload`| [Hot Reloading]({{< ref components-concept.md >}}) | v1.13 | -| **Subscription Hot Reloading** | Allows for declarative subscriptions to be "hot reloaded". A subscription is reloaded either when it is created/updated/deleted in Kubernetes, or on file in self-hosted mode. In-flight messages are unaffected when reloading. | `HotReload`| [Hot Reloading]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | v1.14 | \ No newline at end of file +| **Subscription Hot Reloading** | Allows for declarative subscriptions to be "hot reloaded". A subscription is reloaded either when it is created/updated/deleted in Kubernetes, or on file in self-hosted mode. In-flight messages are unaffected when reloading. | `HotReload`| [Hot Reloading]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | v1.14 | +| **Scheduler Actor Reminders** | Scheduler actor reminders are actor reminders stored in the Scheduler control plane service, as opposed to the Placement control plane service actor reminder system. `SchedulerReminders` defaults to `true`. To disable Scheduler actor reminders, change it to `false`. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) | v1.14 | \ No newline at end of file From ef278281ada4e809c9c967533304c437db5c9a54 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Wed, 4 Dec 2024 11:15:11 -0500 Subject: [PATCH 07/31] update per confirmation Signed-off-by: Hannah Hunter --- .../building-blocks/jobs/jobs-overview.md | 4 +++- .../content/en/operations/support/support-preview-features.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md index 4eb98b1e5fb..dfb2a54b397 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md +++ b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md @@ -61,7 +61,9 @@ The Scheduler service enables the scheduling of jobs to scale across multiple re ### Actor reminders -Actors have actor reminders, but present some limitations involving scalability using the Placement service implementation. You can make reminders more scalable by using `SchedulerReminders` in the configuration for your actor application. `SchedulerReminders` defaults to `true`. To disable Scheduler actor reminders, change it to `false`. +Actors have actor reminders, but present some limitations involving scalability using the Placement service implementation. You can make reminders more scalable by using `SchedulerReminders` in the configuration for your actor application. + +The `SchedulerReminders` preview feature flag defaults to `true`. To disable Scheduler actor reminders, you can manually set it to `false`. ## Try out the jobs API diff --git a/daprdocs/content/en/operations/support/support-preview-features.md b/daprdocs/content/en/operations/support/support-preview-features.md index a618e47db98..c6a76667350 100644 --- a/daprdocs/content/en/operations/support/support-preview-features.md +++ b/daprdocs/content/en/operations/support/support-preview-features.md @@ -22,4 +22,4 @@ For CLI there is no explicit opt-in, just the version that this was first made a | **Actor State TTL** | Allow actors to save records to state stores with Time To Live (TTL) set to automatically clean up old data. In its current implementation, actor state with TTL may not be reflected correctly by clients, read [Actor State Transactions]({{< ref actors_api.md >}}) for more information. | `ActorStateTTL` | [Actor State Transactions]({{< ref actors_api.md >}}) | v1.11 | | **Component Hot Reloading** | Allows for Dapr-loaded components to be "hot reloaded". A component spec is reloaded when it is created/updated/deleted in Kubernetes or on file when running in self-hosted mode. Ignores changes to actor state stores and workflow backends. | `HotReload`| [Hot Reloading]({{< ref components-concept.md >}}) | v1.13 | | **Subscription Hot Reloading** | Allows for declarative subscriptions to be "hot reloaded". A subscription is reloaded either when it is created/updated/deleted in Kubernetes, or on file in self-hosted mode. In-flight messages are unaffected when reloading. | `HotReload`| [Hot Reloading]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | v1.14 | -| **Scheduler Actor Reminders** | Scheduler actor reminders are actor reminders stored in the Scheduler control plane service, as opposed to the Placement control plane service actor reminder system. `SchedulerReminders` defaults to `true`. To disable Scheduler actor reminders, change it to `false`. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) | v1.14 | \ No newline at end of file +| **Scheduler Actor Reminders** | Scheduler actor reminders are actor reminders stored in the Scheduler control plane service, as opposed to the Placement control plane service actor reminder system. The `SchedulerReminders` preview feature flag defaults to `true`, but you can disable Scheduler actor reminders by manually setting it to `false`. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) | v1.14 | \ No newline at end of file From 8e059a38c56782e595dfe03cf014cb433504d711 Mon Sep 17 00:00:00 2001 From: Samantha Coyle Date: Wed, 4 Dec 2024 13:17:23 -0600 Subject: [PATCH 08/31] docs(aws): revamp aws docs + iam role anywhere profile Signed-off-by: Samantha Coyle --- .../integrations/AWS/authenticating-aws.md | 63 ++++++++++++++++--- .../supported-bindings/postgresql.md | 6 +- .../postgresql-configuration-store.md | 6 +- .../supported-pubsub/setup-apache-kafka.md | 14 ++--- .../setup-postgresql-v1.md | 6 +- .../setup-postgresql-v2.md | 6 +- 6 files changed, 73 insertions(+), 28 deletions(-) diff --git a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md index f11565ceb59..1bbfdb49a06 100644 --- a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md +++ b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md @@ -10,22 +10,67 @@ aliases: All Dapr components using various AWS services (DynamoDB, SQS, S3, etc) use a standardized set of attributes for configuration via the AWS SDK. [Learn more about how the AWS SDK handles credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials). -Since you can configure the AWS SDK using the default provider chain, all of the following attributes are optional. Test the component configuration and inspect the log output from the Dapr runtime to ensure that components initialize correctly. +You can configure the AWS SDK using the default provider chain, or using one of the following built-in AWS authentication profiles. Test the component configuration and inspect the log output from the Dapr runtime to ensure that components initialize correctly. -| Attribute | Description | -| --------- | ----------- | -| `region` | Which AWS region to connect to. In some situations (when running Dapr in self-hosted mode, for example), this flag can be provided by the environment variable `AWS_REGION`. Since Dapr sidecar injection doesn't allow configuring environment variables on the Dapr sidecar, it is recommended to always set the `region` attribute in the component spec. | -| `endpoint` | The endpoint is normally handled internally by the AWS SDK. However, in some situations it might make sense to set it locally - for example if developing against [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html). | -| `accessKey` | AWS Access key id. | -| `secretKey` | AWS Secret access key. Use together with `accessKey` to explicitly specify credentials. | -| `sessionToken` | AWS Session token. Used together with `accessKey` and `secretKey`. When using a regular IAM user's access key and secret, a session token is normally not required. | +### AWS: Access Key ID and Secret Access Key +Authenticate to AWS using static Access Key and Secret Key information. You can do this through metadata fields on the component, or by using the [default AWS configuration](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) for this authentication profile. {{% alert title="Important" color="warning" %}} -You **must not** provide AWS access-key, secret-key, and tokens in the definition of the component spec you're using: +You should leverage the loading of the default AWS configuration instead of providing AWS access key, secret key, and tokens in the definition of the component spec you're using: - When running the Dapr sidecar (`daprd`) with your application on EKS (AWS Kubernetes) - If using a node/pod that has already been attached to an IAM policy defining access to AWS resources {{% /alert %}} +| Attribute | Required | Description | Example | +| --------- | ----------- | ----------- | ----------- | +| `region` | Y | Which AWS region to connect to. | "us-east-1" | +| `accessKey` | N | AWS Access key id. | "AKIAIOSFODNN7EXAMPLE" | +| `secretKey` | N | AWS Secret access key. Use together with `accessKey` to explicitly specify credentials. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | +| `sessionToken` | N | AWS Session token. Used together with `accessKey` and `secretKey`. When using a regular IAM user's access key and secret, a session token is normally not required. | | + +### Assume IAM Role +Assume a specific IAM Role. This authentication profile assumes your running the Dapr sidecar on EKS (AWS Kubernetes), or using a node/pod that has already been attached to an IAM policy defining access to AWS resources. + +This authentication profile is only supported on Kafka and PostgreSQL components at this time. + +| Attribute | Required | Description | Example | +| --------- | ----------- | ----------- | ----------- | +| `region` | Y | Which AWS region to connect to. | "us-east-1" | +| `assumeRoleArn` | N | IAM role that has access to AWS resource. This field will be marked required in Dapr 1.17. | "arn:aws:iam::123456789:role/mskRole" | +| `sessionName` | N | The session name for assuming a role. Default is `"DaprDefaultSession"`. | "MyAppSession" | + +### Credentials from Environment Variables +Authentication can be done through setting [environment variables](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html) providing credentials. This supports situations, such as when running Dapr in self-hosted mode where the Dapr sidecar injector doesn't allow for configuring environment variables on the Dapr sidecar. + +There are no metadata fields required for this authentication profile. + +TODO: note kafka/postgres have useAWSIAM fields!! + +### IAM Roles Anywhere +[IAM Roles Anywhere](https://aws.amazon.com/iam/roles-anywhere/) is an AWS service that extends IAM role-based authentication to workloads running outside of AWS. It eliminates the need for long-term credentials by using cryptographically signed certificates, anchored in a trust relationship. This leverages the existing PKI, Dapr Sentry control plane service, to sign X.509 certificates and assign a unique [SPIFFE](https://spiffe.io/) identity to each application. To configure this authentication profile: +1. Create a Trust Anchor in the trusting AWS account by uploading the Dapr certificate bundle as an `External certificate bundle`. +2. Create an IAM role with the resource permissions policy necessary, as well as a trust entity for the Roles Anywhere AWS service. Here, you can specify SPIFFE identities allowed. +3. Create an IAM Profile under the Roles Anywhere service, linking the IAM Role. + +This is the most secure AWS authentication profile as Dapr handles credential rotation at half the session lifespan. + + +| Attribute | Required | Description | Example | +| --------- | ----------- | ----------- | ----------- | +| `trustAnchorArn` | Y | ARN of the Trust Anchor in the AWS account granting trust to the Dapr Certificate Authority. | arn:aws:rolesanywhere:us-west-1:012345678910:trust-anchor/01234568-0123-0123-0123-012345678901 | +| `trustProfileArn` | Y | ARN of the AWS IAM Profile in the trusting AWS account. | arn:aws:rolesanywhere:us-west-1:012345678910:profile/01234568-0123-0123-0123-012345678901 | +| `assumeRoleArn` | Y | ARN of the AWS IAM role to assume in the trusting AWS account. | arn:aws:iam:012345678910:role/exampleIAMRoleName | + +### Additional Optional Fields + +Some AWS components include additional optional fields: + +| Attribute | Description | +| --------- | ----------- | +| `endpoint` | N | The endpoint is normally handled internally by the AWS SDK. However, in some situations it might make sense to set it locally - for example if developing against [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html). | + +Furthermore, non-native AWS components such as Kafka and PostgreSQL that support AWS authentication profiles have metadata fields to trigger the AWS authentication logic. Be sure to check your specific component documentation. + ## Alternatives to explicitly specifying credentials in component manifest files In production scenarios, it is recommended to use a solution such as: diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md b/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md index 97617eb3eb3..698cb5af886 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md @@ -64,9 +64,9 @@ The AWS authentication token will be dynamically rotated before it's expiration |--------|:--------:|---------|---------| | `useAWSIAM` | Y | Must be set to `true` to enable the component to retrieve access tokens from AWS IAM. This authentication method only works with AWS Relational Database Service for PostgreSQL databases. | `"true"` | | `connectionString` | Y | The connection string for the PostgreSQL database.
    This must contain an already existing user, which corresponds to the name of the user created inside PostgreSQL that maps to the AWS IAM policy. This connection string should not contain any password. Note that the database name field is denoted by dbname with AWS. | `"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=my_db sslmode=require"`| -| `awsRegion` | Y | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | -| `awsAccessKey` | Y | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | -| `awsSecretKey` | Y | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | +| `awsRegion` | N | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | +| `awsAccessKey` | N | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | +| `awsSecretKey` | N | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | | `awsSessionToken` | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | ### Other metadata options diff --git a/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md b/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md index 29d7859c326..ba1d70ef1ff 100644 --- a/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md +++ b/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md @@ -90,9 +90,9 @@ The AWS authentication token will be dynamically rotated before it's expiration |--------|:--------:|---------|---------| | `useAWSIAM` | Y | Must be set to `true` to enable the component to retrieve access tokens from AWS IAM. This authentication method only works with AWS Relational Database Service for PostgreSQL databases. | `"true"` | | `connectionString` | Y | The connection string for the PostgreSQL database.
    This must contain an already existing user, which corresponds to the name of the user created inside PostgreSQL that maps to the AWS IAM policy. This connection string should not contain any password. Note that the database name field is denoted by dbname with AWS. | `"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=my_db sslmode=require"`| -| `awsRegion` | Y | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | -| `awsAccessKey` | Y | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | -| `awsSecretKey` | Y | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | +| `awsRegion` | N | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | +| `awsAccessKey` | N | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | +| `awsSecretKey` | N | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | | `awsSessionToken` | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | ### Other metadata options diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md index c6f71888370..cfc6021b5cb 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md @@ -109,7 +109,7 @@ spec: | awsSecretKey | N | The secret key associated with the access key. | `"secretKey"` | awsSessionToken | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"sessionToken"` | awsIamRoleArn | N | IAM role that has access to AWS Managed Streaming for Apache Kafka (MSK). This is another option to authenticate with MSK aside from the AWS Credentials. | `"arn:aws:iam::123456789:role/mskRole"` -| awsStsSessionName | N | Represents the session name for assuming a role. | `"MSKSASLDefaultSession"` +| awsStsSessionName | N | Represents the session name for assuming a role. | `"DaprDefaultSession"` | schemaRegistryURL | N | Required when using Schema Registry Avro serialization/deserialization. The Schema Registry URL. | `http://localhost:8081` | | schemaRegistryAPIKey | N | When using Schema Registry Avro serialization/deserialization. The Schema Registry credentials API Key. | `XYAXXAZ` | | schemaRegistryAPISecret | N | When using Schema Registry Avro serialization/deserialization. The Schema Registry credentials API Secret. | `ABCDEFGMEADFF` | @@ -354,16 +354,16 @@ spec: value: "awsiam" - name: awsRegion # Required. value: "us-west-1" - - name: awsAccessKey # Optional. + - name: accessKey # Optional. value: - - name: awsSecretKey # Optional. + - name: secretKey # Optional. value: - - name: awsSessionToken # Optional. + - name: sessionToken # Optional. value: - - name: awsIamRoleArn # Optional. + - name: assumeRoleArn # Optional. value: "arn:aws:iam::123456789:role/mskRole" - - name: awsStsSessionName # Optional. - value: "MSKSASLDefaultSession" + - name: sessionName # Optional. + value: "DaprDefaultSession" ``` ### Communication using TLS diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v1.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v1.md index 8cec85ad16a..53e4c0e75d1 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v1.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v1.md @@ -94,9 +94,9 @@ The AWS authentication token will be dynamically rotated before it's expiration |--------|:--------:|---------|---------| | `useAWSIAM` | Y | Must be set to `true` to enable the component to retrieve access tokens from AWS IAM. This authentication method only works with AWS Relational Database Service for PostgreSQL databases. | `"true"` | | `connectionString` | Y | The connection string for the PostgreSQL database.
    This must contain an already existing user, which corresponds to the name of the user created inside PostgreSQL that maps to the AWS IAM policy. This connection string should not contain any password. Note that the database name field is denoted by dbname with AWS. | `"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=my_db sslmode=require"`| -| `awsRegion` | Y | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | -| `awsAccessKey` | Y | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | -| `awsSecretKey` | Y | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | +| `awsRegion` | N | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | +| `awsAccessKey` | N | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | +| `awsSecretKey` | N | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | | `awsSessionToken` | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | ### Other metadata options diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md index 3223867787f..9f8842bfb66 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md @@ -94,9 +94,9 @@ The AWS authentication token will be dynamically rotated before it's expiration |--------|:--------:|---------|---------| | `useAWSIAM` | Y | Must be set to `true` to enable the component to retrieve access tokens from AWS IAM. This authentication method only works with AWS Relational Database Service for PostgreSQL databases. | `"true"` | | `connectionString` | Y | The connection string for the PostgreSQL database.
    This must contain an already existing user, which corresponds to the name of the user created inside PostgreSQL that maps to the AWS IAM policy. This connection string should not contain any password. Note that the database name field is denoted by dbname with AWS. | `"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=my_db sslmode=require"`| -| `awsRegion` | Y | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | -| `awsAccessKey` | Y | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | -| `awsSecretKey` | Y | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | +| `awsRegion` | N | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | +| `awsAccessKey` | N | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | +| `awsSecretKey` | N | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | | `awsSessionToken` | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | ### Other metadata options From f4c8ae82a7efad0e09304ff2e5f1a6ed209dd05b Mon Sep 17 00:00:00 2001 From: Samantha Coyle Date: Wed, 4 Dec 2024 13:27:54 -0600 Subject: [PATCH 09/31] style: clean up Signed-off-by: Samantha Coyle --- .../integrations/AWS/authenticating-aws.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md index 1bbfdb49a06..ab738c5af05 100644 --- a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md +++ b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md @@ -44,8 +44,6 @@ Authentication can be done through setting [environment variables](https://docs. There are no metadata fields required for this authentication profile. -TODO: note kafka/postgres have useAWSIAM fields!! - ### IAM Roles Anywhere [IAM Roles Anywhere](https://aws.amazon.com/iam/roles-anywhere/) is an AWS service that extends IAM role-based authentication to workloads running outside of AWS. It eliminates the need for long-term credentials by using cryptographically signed certificates, anchored in a trust relationship. This leverages the existing PKI, Dapr Sentry control plane service, to sign X.509 certificates and assign a unique [SPIFFE](https://spiffe.io/) identity to each application. To configure this authentication profile: 1. Create a Trust Anchor in the trusting AWS account by uploading the Dapr certificate bundle as an `External certificate bundle`. From 4ca705b541afc6ce1614c0014c82f6e46caef253 Mon Sep 17 00:00:00 2001 From: Samantha Coyle Date: Wed, 4 Dec 2024 14:09:03 -0600 Subject: [PATCH 10/31] style: add deprecation notices and clean up Signed-off-by: Samantha Coyle --- .../integrations/AWS/authenticating-aws.md | 61 +++++++++---------- .../supported-bindings/postgresql.md | 8 +-- .../postgresql-configuration-store.md | 8 +-- .../supported-pubsub/setup-apache-kafka.md | 18 +++--- .../setup-postgresql-v2.md | 8 +-- 5 files changed, 52 insertions(+), 51 deletions(-) diff --git a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md index ab738c5af05..54f7df40ba4 100644 --- a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md +++ b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md @@ -8,50 +8,49 @@ aliases: - /developing-applications/integrations/authenticating/authenticating-aws/ --- -All Dapr components using various AWS services (DynamoDB, SQS, S3, etc) use a standardized set of attributes for configuration via the AWS SDK. [Learn more about how the AWS SDK handles credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials). +Dapr components leveraging AWS services (e.g., DynamoDB, SQS, S3) utilize standardized configuration attributes via the AWS SDK. [Learn more about how the AWS SDK handles credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials). -You can configure the AWS SDK using the default provider chain, or using one of the following built-in AWS authentication profiles. Test the component configuration and inspect the log output from the Dapr runtime to ensure that components initialize correctly. +You can configure authentication using the AWS SDK’s default provider chain or one of the predefined AWS authentication profiles outlined below. Verify your component configuration by testing and inspecting Dapr runtime logs to confirm proper initialization. -### AWS: Access Key ID and Secret Access Key -Authenticate to AWS using static Access Key and Secret Key information. You can do this through metadata fields on the component, or by using the [default AWS configuration](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) for this authentication profile. +### Authentication Profiles + +#### 1. Access Key ID and Secret Access Key +Use static Access Key and Secret Key credentials, either through component metadata fields or via [default AWS configuration](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html). {{% alert title="Important" color="warning" %}} -You should leverage the loading of the default AWS configuration instead of providing AWS access key, secret key, and tokens in the definition of the component spec you're using: -- When running the Dapr sidecar (`daprd`) with your application on EKS (AWS Kubernetes) -- If using a node/pod that has already been attached to an IAM policy defining access to AWS resources +Prefer loading credentials via the default AWS configuration in scenarios such as: +- Running the Dapr sidecar (`daprd`) with your application on EKS (AWS Kubernetes). +- Using nodes or pods attached to IAM policies that define AWS resource access. {{% /alert %}} | Attribute | Required | Description | Example | | --------- | ----------- | ----------- | ----------- | -| `region` | Y | Which AWS region to connect to. | "us-east-1" | +| `region` | Y | AWS region to connect to. | "us-east-1" | | `accessKey` | N | AWS Access key id. | "AKIAIOSFODNN7EXAMPLE" | -| `secretKey` | N | AWS Secret access key. Use together with `accessKey` to explicitly specify credentials. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | -| `sessionToken` | N | AWS Session token. Used together with `accessKey` and `secretKey`. When using a regular IAM user's access key and secret, a session token is normally not required. | | - -### Assume IAM Role -Assume a specific IAM Role. This authentication profile assumes your running the Dapr sidecar on EKS (AWS Kubernetes), or using a node/pod that has already been attached to an IAM policy defining access to AWS resources. +| `secretKey` | N | AWS Secret access key, used alongside `accessKey`. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | +| `sessionToken` | N | AWS Session token, used with `accessKey` and `secretKey`. Often unnecessary for IAM user keys. | | -This authentication profile is only supported on Kafka and PostgreSQL components at this time. +#### 2. Assume IAM Role +This profile allows Dapr to assume a specific IAM Role. Typically used when the Dapr sidecar runs on EKS or nodes/pods linked to IAM policies. Currently supported by Kafka and PostgreSQL components. | Attribute | Required | Description | Example | | --------- | ----------- | ----------- | ----------- | -| `region` | Y | Which AWS region to connect to. | "us-east-1" | -| `assumeRoleArn` | N | IAM role that has access to AWS resource. This field will be marked required in Dapr 1.17. | "arn:aws:iam::123456789:role/mskRole" | -| `sessionName` | N | The session name for assuming a role. Default is `"DaprDefaultSession"`. | "MyAppSession" | +| `region` | Y | AWS region to connect to. | "us-east-1" | +| `assumeRoleArn` | N | ARN of the IAM role with AWS resource access. Will be required in Dapr 1.17. | "arn:aws:iam::123456789:role/mskRole" | +| `sessionName` | N | Session name for role assumption. Default is `"DaprDefaultSession"`. | "MyAppSession" | -### Credentials from Environment Variables -Authentication can be done through setting [environment variables](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html) providing credentials. This supports situations, such as when running Dapr in self-hosted mode where the Dapr sidecar injector doesn't allow for configuring environment variables on the Dapr sidecar. +#### Credentials from Environment Variables +Authenticate using [environment variables](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html). This is especially useful for Dapr in self-hosted mode where sidecar injectors don’t configure environment variables. There are no metadata fields required for this authentication profile. -### IAM Roles Anywhere -[IAM Roles Anywhere](https://aws.amazon.com/iam/roles-anywhere/) is an AWS service that extends IAM role-based authentication to workloads running outside of AWS. It eliminates the need for long-term credentials by using cryptographically signed certificates, anchored in a trust relationship. This leverages the existing PKI, Dapr Sentry control plane service, to sign X.509 certificates and assign a unique [SPIFFE](https://spiffe.io/) identity to each application. To configure this authentication profile: -1. Create a Trust Anchor in the trusting AWS account by uploading the Dapr certificate bundle as an `External certificate bundle`. -2. Create an IAM role with the resource permissions policy necessary, as well as a trust entity for the Roles Anywhere AWS service. Here, you can specify SPIFFE identities allowed. -3. Create an IAM Profile under the Roles Anywhere service, linking the IAM Role. - -This is the most secure AWS authentication profile as Dapr handles credential rotation at half the session lifespan. +#### IAM Roles Anywhere +[IAM Roles Anywhere](https://aws.amazon.com/iam/roles-anywhere/) extends IAM role-based authentication to external workloads. It eliminates the need for long-term credentials by using cryptographically signed certificates, anchored in a trust relationship using Dapr PKI. Dapr SPIFFE identity X.509 certificates are used to authenticate to AWS services, and Dapr handles credential rotation at half the session lifespan. +To configure this authentication profile: +1. Create a Trust Anchor in the trusting AWS account using the Dapr certificate bundle as an `External certificate bundle`. +2. Create an IAM role with the resource permissions policy necessary, as well as a trust entity for the Roles Anywhere AWS service. Here, you specify SPIFFE identities allowed. +3. Create an IAM Profile under the Roles Anywhere service, linking the IAM Role. | Attribute | Required | Description | Example | | --------- | ----------- | ----------- | ----------- | @@ -59,15 +58,15 @@ This is the most secure AWS authentication profile as Dapr handles credential ro | `trustProfileArn` | Y | ARN of the AWS IAM Profile in the trusting AWS account. | arn:aws:rolesanywhere:us-west-1:012345678910:profile/01234568-0123-0123-0123-012345678901 | | `assumeRoleArn` | Y | ARN of the AWS IAM role to assume in the trusting AWS account. | arn:aws:iam:012345678910:role/exampleIAMRoleName | -### Additional Optional Fields +### Additional Fields Some AWS components include additional optional fields: -| Attribute | Description | -| --------- | ----------- | -| `endpoint` | N | The endpoint is normally handled internally by the AWS SDK. However, in some situations it might make sense to set it locally - for example if developing against [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html). | +| Attribute | Required | Description | Example | +| --------- | ----------- | ----------- | ----------- | +| `endpoint` | N | The endpoint is normally handled internally by the AWS SDK. However, in some situations it might make sense to set it locally - for example if developing against [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html). | | -Furthermore, non-native AWS components such as Kafka and PostgreSQL that support AWS authentication profiles have metadata fields to trigger the AWS authentication logic. Be sure to check your specific component documentation. +Furthermore, non-native AWS components such as Kafka and PostgreSQL that support AWS authentication profiles have metadata fields to trigger the AWS authentication logic. Be sure to check specific component documentation. ## Alternatives to explicitly specifying credentials in component manifest files diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md b/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md index 698cb5af886..a77814b8e1e 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/postgresql.md @@ -64,10 +64,10 @@ The AWS authentication token will be dynamically rotated before it's expiration |--------|:--------:|---------|---------| | `useAWSIAM` | Y | Must be set to `true` to enable the component to retrieve access tokens from AWS IAM. This authentication method only works with AWS Relational Database Service for PostgreSQL databases. | `"true"` | | `connectionString` | Y | The connection string for the PostgreSQL database.
    This must contain an already existing user, which corresponds to the name of the user created inside PostgreSQL that maps to the AWS IAM policy. This connection string should not contain any password. Note that the database name field is denoted by dbname with AWS. | `"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=my_db sslmode=require"`| -| `awsRegion` | N | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | -| `awsAccessKey` | N | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | -| `awsSecretKey` | N | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | -| `awsSessionToken` | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | +| `awsRegion` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'region' instead. The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | +| `awsAccessKey` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'accessKey' instead. AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | +| `awsSecretKey` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'secretKey' instead. The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | +| `awsSessionToken` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'sessionToken' instead. AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | ### Other metadata options diff --git a/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md b/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md index ba1d70ef1ff..ea4868fe34c 100644 --- a/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md +++ b/daprdocs/content/en/reference/components-reference/supported-configuration-stores/postgresql-configuration-store.md @@ -90,10 +90,10 @@ The AWS authentication token will be dynamically rotated before it's expiration |--------|:--------:|---------|---------| | `useAWSIAM` | Y | Must be set to `true` to enable the component to retrieve access tokens from AWS IAM. This authentication method only works with AWS Relational Database Service for PostgreSQL databases. | `"true"` | | `connectionString` | Y | The connection string for the PostgreSQL database.
    This must contain an already existing user, which corresponds to the name of the user created inside PostgreSQL that maps to the AWS IAM policy. This connection string should not contain any password. Note that the database name field is denoted by dbname with AWS. | `"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=my_db sslmode=require"`| -| `awsRegion` | N | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | -| `awsAccessKey` | N | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | -| `awsSecretKey` | N | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | -| `awsSessionToken` | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | +| `awsRegion` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'region' instead. The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | +| `awsAccessKey` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'accessKey' instead. AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | +| `awsSecretKey` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'secretKey' instead. The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | +| `awsSessionToken` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'sessionToken' instead. AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | ### Other metadata options diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md index cfc6021b5cb..503500ca8e2 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md @@ -104,12 +104,12 @@ spec: | oidcClientSecret | N | The OAuth2 client secret that has been provisioned in the identity provider: Required when `authType` is set to `oidc` | `"KeFg23!"` | | oidcScopes | N | Comma-delimited list of OAuth2/OIDC scopes to request with the access token. Recommended when `authType` is set to `oidc`. Defaults to `"openid"` | `"openid,kafka-prod"` | | oidcExtensions | N | String containing a JSON-encoded dictionary of OAuth2/OIDC extensions to request with the access token | `{"cluster":"kafka","poolid":"kafkapool"}` | -| awsRegion | N | The AWS region where the Kafka cluster is deployed to. Required when `authType` is set to `awsiam` | `us-west-1` | -| awsAccessKey | N | AWS access key associated with an IAM account. | `"accessKey"` -| awsSecretKey | N | The secret key associated with the access key. | `"secretKey"` -| awsSessionToken | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"sessionToken"` -| awsIamRoleArn | N | IAM role that has access to AWS Managed Streaming for Apache Kafka (MSK). This is another option to authenticate with MSK aside from the AWS Credentials. | `"arn:aws:iam::123456789:role/mskRole"` -| awsStsSessionName | N | Represents the session name for assuming a role. | `"DaprDefaultSession"` +| awsRegion | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'region' instead. The AWS region where the Kafka cluster is deployed to. Required when `authType` is set to `awsiam` | `us-west-1` | +| awsAccessKey | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'accessKey' instead. AWS access key associated with an IAM account. | `"accessKey"` +| awsSecretKey | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'secretKey' instead. The secret key associated with the access key. | `"secretKey"` +| awsSessionToken | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'sessionToken' instead. AWS session token to use. A session token is only required if you are using temporary security credentials. | `"sessionToken"` +| awsIamRoleArn | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'assumeRoleArn' instead. IAM role that has access to AWS Managed Streaming for Apache Kafka (MSK). This is another option to authenticate with MSK aside from the AWS Credentials. | `"arn:aws:iam::123456789:role/mskRole"` +| awsStsSessionName | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'sessionName' instead. Represents the session name for assuming a role. | `"DaprDefaultSession"` | schemaRegistryURL | N | Required when using Schema Registry Avro serialization/deserialization. The Schema Registry URL. | `http://localhost:8081` | | schemaRegistryAPIKey | N | When using Schema Registry Avro serialization/deserialization. The Schema Registry credentials API Key. | `XYAXXAZ` | | schemaRegistryAPISecret | N | When using Schema Registry Avro serialization/deserialization. The Schema Registry credentials API Secret. | `ABCDEFGMEADFF` | @@ -332,7 +332,7 @@ spec: Authenticating with AWS IAM is supported with MSK. Setting `authType` to `awsiam` uses AWS SDK to generate auth tokens to authenticate. {{% alert title="Note" color="primary" %}} -The only required metadata field is `awsRegion`. If no `awsAccessKey` and `awsSecretKey` are provided, you can use AWS IAM roles for service accounts to have password-less authentication to your Kafka cluster. +The only required metadata field is `region`. If no `acessKey` and `secretKey` are provided, you can use AWS IAM roles for service accounts to have password-less authentication to your Kafka cluster. {{% /alert %}} ```yaml @@ -352,7 +352,7 @@ spec: value: "my-dapr-app-id" - name: authType # Required. value: "awsiam" - - name: awsRegion # Required. + - name: region # Required. value: "us-west-1" - name: accessKey # Optional. value: @@ -540,6 +540,8 @@ app.include_router(router) ``` {{% /codetab %}} +{{< /tabs >}} + ## Receiving message headers with special characters The consumer application may be required to receive message headers that include special characters, which may cause HTTP protocol validation errors. diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md index 9f8842bfb66..d4e21f17ba8 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-postgresql-v2.md @@ -94,10 +94,10 @@ The AWS authentication token will be dynamically rotated before it's expiration |--------|:--------:|---------|---------| | `useAWSIAM` | Y | Must be set to `true` to enable the component to retrieve access tokens from AWS IAM. This authentication method only works with AWS Relational Database Service for PostgreSQL databases. | `"true"` | | `connectionString` | Y | The connection string for the PostgreSQL database.
    This must contain an already existing user, which corresponds to the name of the user created inside PostgreSQL that maps to the AWS IAM policy. This connection string should not contain any password. Note that the database name field is denoted by dbname with AWS. | `"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=my_db sslmode=require"`| -| `awsRegion` | N | The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | -| `awsAccessKey` | N | AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | -| `awsSecretKey` | N | The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | -| `awsSessionToken` | N | AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | +| `awsRegion` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'region' instead. The AWS Region where the AWS Relational Database Service is deployed to. | `"us-east-1"` | +| `awsAccessKey` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'accessKey' instead. AWS access key associated with an IAM account | `"AKIAIOSFODNN7EXAMPLE"` | +| `awsSecretKey` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'secretKey' instead. The secret key associated with the access key | `"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` | +| `awsSessionToken` | N | This maintains backwards compatibility with existing fields. It will be deprecated as of Dapr 1.17. Use 'sessionToken' instead. AWS session token to use. A session token is only required if you are using temporary security credentials. | `"TOKEN"` | ### Other metadata options From c0fccb2bcfeff05d136723e4e2591429a0d56455 Mon Sep 17 00:00:00 2001 From: Bilgin Ibryam Date: Wed, 4 Dec 2024 20:50:57 +0000 Subject: [PATCH 11/31] Reworded concurency control doc --- .../en/operations/configuration/control-concurrency.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/operations/configuration/control-concurrency.md b/daprdocs/content/en/operations/configuration/control-concurrency.md index 976b78ab980..8bfdc044cd4 100644 --- a/daprdocs/content/en/operations/configuration/control-concurrency.md +++ b/daprdocs/content/en/operations/configuration/control-concurrency.md @@ -8,14 +8,14 @@ description: "Learn how to control how many requests and events can invoke your Typically, in distributed computing, you may only want to allow for a given number of requests to execute concurrently. Using Dapr's `app-max-concurrency`, you can control how many requests and events can invoke your application simultaneously. -Default `app-max-concurreny` is set to `-1`, meaning no concurrency. +Default `app-max-concurreny` is set to `-1`, meaning no concurrency limit is enforced. ## Different approaches While this guide focuses on `app-max-concurrency`, you can also limit request rate per second using the **`middleware.http.ratelimit`** middleware. However, it's important to understand the difference between the two approaches: - `middleware.http.ratelimit`: Time bound and limits the number of requests per second -- `app-max-concurrency`: Specifies the number of concurrent requests (and events) at any point of time. +- `app-max-concurrency`: Specifies the max number of concurrent requests (and events) at any point of time. See [Rate limit middleware]({{< ref middleware-rate-limit.md >}}) for more information about that approach. @@ -46,7 +46,7 @@ To set concurrency limits with the Dapr CLI for running on your local dev machin dapr run --app-max-concurrency 1 --app-port 5000 python ./app.py ``` -The above example effectively turns your app into a single concurrent service. +The above example effectively turns your app into a sequential processing service. {{% /codetab %}} From 2952bf326900662948cc894e194b190e6ec17a4a Mon Sep 17 00:00:00 2001 From: Samantha Coyle Date: Wed, 4 Dec 2024 14:59:17 -0600 Subject: [PATCH 12/31] fix: address feedback so far Signed-off-by: Samantha Coyle --- .../integrations/AWS/authenticating-aws.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md index 54f7df40ba4..7ae9c5b5d5a 100644 --- a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md +++ b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md @@ -8,10 +8,14 @@ aliases: - /developing-applications/integrations/authenticating/authenticating-aws/ --- -Dapr components leveraging AWS services (e.g., DynamoDB, SQS, S3) utilize standardized configuration attributes via the AWS SDK. [Learn more about how the AWS SDK handles credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials). +Dapr components leveraging AWS services (for example, DynamoDB, SQS, S3) utilize standardized configuration attributes via the AWS SDK. [Learn more about how the AWS SDK handles credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials). You can configure authentication using the AWS SDK’s default provider chain or one of the predefined AWS authentication profiles outlined below. Verify your component configuration by testing and inspecting Dapr runtime logs to confirm proper initialization. +### Terminology +- **ARN (Amazon Resource Name):** A unique identifier used to specify AWS resources. Format: arn:partition:service:region:account-id:resource. Example: arn:aws:iam::123456789012:role/example-role. +- **IAM (Identity and Access Management):** AWS's service for managing access to AWS resources securely. + ### Authentication Profiles #### 1. Access Key ID and Secret Access Key From e9f742e642bdfea75cfb300341cc359012543f34 Mon Sep 17 00:00:00 2001 From: Samantha Coyle Date: Wed, 4 Dec 2024 16:22:17 -0600 Subject: [PATCH 13/31] style: rm numbers on titles Signed-off-by: Samantha Coyle --- .../integrations/AWS/authenticating-aws.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md index 7ae9c5b5d5a..edd32e17036 100644 --- a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md +++ b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md @@ -18,7 +18,7 @@ You can configure authentication using the AWS SDK’s default provider chain or ### Authentication Profiles -#### 1. Access Key ID and Secret Access Key +#### Access Key ID and Secret Access Key Use static Access Key and Secret Key credentials, either through component metadata fields or via [default AWS configuration](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html). {{% alert title="Important" color="warning" %}} @@ -34,7 +34,7 @@ Prefer loading credentials via the default AWS configuration in scenarios such a | `secretKey` | N | AWS Secret access key, used alongside `accessKey`. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | | `sessionToken` | N | AWS Session token, used with `accessKey` and `secretKey`. Often unnecessary for IAM user keys. | | -#### 2. Assume IAM Role +#### Assume IAM Role This profile allows Dapr to assume a specific IAM Role. Typically used when the Dapr sidecar runs on EKS or nodes/pods linked to IAM policies. Currently supported by Kafka and PostgreSQL components. | Attribute | Required | Description | Example | From 7bc95b5a53c95680e31638b6cc09ddd459f32a5a Mon Sep 17 00:00:00 2001 From: Whit Waldo Date: Fri, 6 Dec 2024 00:50:50 -0600 Subject: [PATCH 14/31] Crypto is still in alpha, so the URLs shouldn't point to v1.0 values Signed-off-by: Whit Waldo --- daprdocs/content/en/reference/api/cryptography_api.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/daprdocs/content/en/reference/api/cryptography_api.md b/daprdocs/content/en/reference/api/cryptography_api.md index 336088f23e3..c0c4824277b 100644 --- a/daprdocs/content/en/reference/api/cryptography_api.md +++ b/daprdocs/content/en/reference/api/cryptography_api.md @@ -20,7 +20,7 @@ This endpoint lets you encrypt a value provided as a byte array using a specifie ### HTTP Request ``` -PUT http://localhost:/v1.0/crypto//encrypt +PUT http://localhost:/v1.0-alpha1/crypto//encrypt ``` #### URL Parameters @@ -59,7 +59,7 @@ returns an array of bytes with the encrypted payload. ### Examples ```shell -curl http://localhost:3500/v1.0/crypto/myAzureKeyVault/encrypt \ +curl http://localhost:3500/v1.0-alpha1/crypto/myAzureKeyVault/encrypt \ -X PUT \ -H "dapr-key-name: myCryptoKey" \ -H "dapr-key-wrap-algorithm: aes-gcm" \ @@ -81,7 +81,7 @@ This endpoint lets you decrypt a value provided as a byte array using a specifie #### HTTP Request ``` -PUT curl http://localhost:3500/v1.0/crypto//decrypt +PUT curl http://localhost:3500/v1.0-alpha1/crypto//decrypt ``` #### URL Parameters @@ -116,7 +116,7 @@ returns an array of bytes representing the decrypted payload. ### Examples ```bash -curl http://localhost:3500/v1.0/crypto/myAzureKeyVault/decrypt \ +curl http://localhost:3500/v1.0-alpha1/crypto/myAzureKeyVault/decrypt \ -X PUT -H "dapr-key-name: myCryptoKey"\ -H "Content-Type: application/octet-stream" \ From 27c401e58117c1b4b089749a661b68ef385a4388 Mon Sep 17 00:00:00 2001 From: Samantha Coyle Date: Fri, 6 Dec 2024 12:57:11 -0600 Subject: [PATCH 15/31] style: last few tweaks Signed-off-by: Samantha Coyle --- .../integrations/AWS/authenticating-aws.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md index edd32e17036..10fb8680a17 100644 --- a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md +++ b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md @@ -13,7 +13,7 @@ Dapr components leveraging AWS services (for example, DynamoDB, SQS, S3) utilize You can configure authentication using the AWS SDK’s default provider chain or one of the predefined AWS authentication profiles outlined below. Verify your component configuration by testing and inspecting Dapr runtime logs to confirm proper initialization. ### Terminology -- **ARN (Amazon Resource Name):** A unique identifier used to specify AWS resources. Format: arn:partition:service:region:account-id:resource. Example: arn:aws:iam::123456789012:role/example-role. +- **ARN (Amazon Resource Name):** A unique identifier used to specify AWS resources. Format: `arn:partition:service:region:account-id:resource`. Example: `arn:aws:iam::123456789012:role/example-role`. - **IAM (Identity and Access Management):** AWS's service for managing access to AWS resources securely. ### Authentication Profiles @@ -30,8 +30,8 @@ Prefer loading credentials via the default AWS configuration in scenarios such a | Attribute | Required | Description | Example | | --------- | ----------- | ----------- | ----------- | | `region` | Y | AWS region to connect to. | "us-east-1" | -| `accessKey` | N | AWS Access key id. | "AKIAIOSFODNN7EXAMPLE" | -| `secretKey` | N | AWS Secret access key, used alongside `accessKey`. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | +| `accessKey` | N | AWS Access key id. Will be required in Dapr 1.17. | "AKIAIOSFODNN7EXAMPLE" | +| `secretKey` | N | AWS Secret access key, used alongside `accessKey`. Will be required in Dapr 1.17. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | | `sessionToken` | N | AWS Session token, used with `accessKey` and `secretKey`. Often unnecessary for IAM user keys. | | #### Assume IAM Role From eaeba364b1c494ab64dd0cd79f746864a6fddbc1 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Tue, 10 Dec 2024 13:41:38 -0500 Subject: [PATCH 16/31] mark updates pt 1 Signed-off-by: Hannah Hunter --- daprdocs/content/en/concepts/dapr-services/scheduler.md | 2 +- .../building-blocks/jobs/jobs-overview.md | 6 ++++-- .../en/operations/support/support-preview-features.md | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/daprdocs/content/en/concepts/dapr-services/scheduler.md b/daprdocs/content/en/concepts/dapr-services/scheduler.md index 07050d391dd..53fd0ddd19e 100644 --- a/daprdocs/content/en/concepts/dapr-services/scheduler.md +++ b/daprdocs/content/en/concepts/dapr-services/scheduler.md @@ -11,7 +11,7 @@ The diagram below shows how the Scheduler service is used via the jobs API when Diagram showing the Scheduler control plane service and the jobs API -The Scheduler service is deployed by default, including for [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) (actor reminders stored in the Scheduler control plane service as opposed to the Placement control plane service actor reminder system) and workflows. +The Scheduler service is used by default for [actor scheduler reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) where actor reminders, which are also used by workflows, are stored in the Scheduler service as opposed to the Placement service. ## Self-hosted mode diff --git a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md index dfb2a54b397..facae8de2f6 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md +++ b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md @@ -61,9 +61,11 @@ The Scheduler service enables the scheduling of jobs to scale across multiple re ### Actor reminders -Actors have actor reminders, but present some limitations involving scalability using the Placement service implementation. You can make reminders more scalable by using `SchedulerReminders` in the configuration for your actor application. +Actors have reminders; the Scheduler service is used by default for actor reminders (which are also used by workflows) to make them more scalable. -The `SchedulerReminders` preview feature flag defaults to `true`. To disable Scheduler actor reminders, you can manually set it to `false`. +> **Note:** In earlier releases, the Placement service was used for actor reminders. This is no longer recommended. + +The `SchedulerReminders` preview feature defaults to `true`. To disable actor scheduler reminders, you can set it to `false`. ## Try out the jobs API diff --git a/daprdocs/content/en/operations/support/support-preview-features.md b/daprdocs/content/en/operations/support/support-preview-features.md index c6a76667350..88c00f6492a 100644 --- a/daprdocs/content/en/operations/support/support-preview-features.md +++ b/daprdocs/content/en/operations/support/support-preview-features.md @@ -22,4 +22,4 @@ For CLI there is no explicit opt-in, just the version that this was first made a | **Actor State TTL** | Allow actors to save records to state stores with Time To Live (TTL) set to automatically clean up old data. In its current implementation, actor state with TTL may not be reflected correctly by clients, read [Actor State Transactions]({{< ref actors_api.md >}}) for more information. | `ActorStateTTL` | [Actor State Transactions]({{< ref actors_api.md >}}) | v1.11 | | **Component Hot Reloading** | Allows for Dapr-loaded components to be "hot reloaded". A component spec is reloaded when it is created/updated/deleted in Kubernetes or on file when running in self-hosted mode. Ignores changes to actor state stores and workflow backends. | `HotReload`| [Hot Reloading]({{< ref components-concept.md >}}) | v1.13 | | **Subscription Hot Reloading** | Allows for declarative subscriptions to be "hot reloaded". A subscription is reloaded either when it is created/updated/deleted in Kubernetes, or on file in self-hosted mode. In-flight messages are unaffected when reloading. | `HotReload`| [Hot Reloading]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | v1.14 | -| **Scheduler Actor Reminders** | Scheduler actor reminders are actor reminders stored in the Scheduler control plane service, as opposed to the Placement control plane service actor reminder system. The `SchedulerReminders` preview feature flag defaults to `true`, but you can disable Scheduler actor reminders by manually setting it to `false`. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) | v1.14 | \ No newline at end of file +| **Scheduler Actor Reminders** | Scheduler actor reminders are actor reminders stored in the Scheduler control plane service, as opposed to the Placement control plane service actor reminder system. The `SchedulerReminders` preview feature defaults to `true`, but you can disable Scheduler actor reminders by setting it to `false`. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) | v1.14 | \ No newline at end of file From afdc4ea1dbe6ccba55987febe9022e06f7add489 Mon Sep 17 00:00:00 2001 From: Samantha Coyle Date: Tue, 10 Dec 2024 14:35:48 -0600 Subject: [PATCH 17/31] style: update version to include the v prefix Signed-off-by: Samantha Coyle --- .../integrations/AWS/authenticating-aws.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md index 10fb8680a17..94757e86bb1 100644 --- a/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md +++ b/daprdocs/content/en/developing-applications/integrations/AWS/authenticating-aws.md @@ -30,8 +30,8 @@ Prefer loading credentials via the default AWS configuration in scenarios such a | Attribute | Required | Description | Example | | --------- | ----------- | ----------- | ----------- | | `region` | Y | AWS region to connect to. | "us-east-1" | -| `accessKey` | N | AWS Access key id. Will be required in Dapr 1.17. | "AKIAIOSFODNN7EXAMPLE" | -| `secretKey` | N | AWS Secret access key, used alongside `accessKey`. Will be required in Dapr 1.17. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | +| `accessKey` | N | AWS Access key id. Will be required in Dapr v1.17. | "AKIAIOSFODNN7EXAMPLE" | +| `secretKey` | N | AWS Secret access key, used alongside `accessKey`. Will be required in Dapr v1.17. | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | | `sessionToken` | N | AWS Session token, used with `accessKey` and `secretKey`. Often unnecessary for IAM user keys. | | #### Assume IAM Role @@ -40,7 +40,7 @@ This profile allows Dapr to assume a specific IAM Role. Typically used when the | Attribute | Required | Description | Example | | --------- | ----------- | ----------- | ----------- | | `region` | Y | AWS region to connect to. | "us-east-1" | -| `assumeRoleArn` | N | ARN of the IAM role with AWS resource access. Will be required in Dapr 1.17. | "arn:aws:iam::123456789:role/mskRole" | +| `assumeRoleArn` | N | ARN of the IAM role with AWS resource access. Will be required in Dapr v1.17. | "arn:aws:iam::123456789:role/mskRole" | | `sessionName` | N | Session name for role assumption. Default is `"DaprDefaultSession"`. | "MyAppSession" | #### Credentials from Environment Variables From c65397345087917b9777b1c5e00538850ad51dcf Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Thu, 12 Dec 2024 15:14:12 -0500 Subject: [PATCH 18/31] updates from Cassie/Mark Signed-off-by: Hannah Hunter --- .../content/en/concepts/dapr-services/scheduler.md | 4 +++- .../building-blocks/actors/actors-timers-reminders.md | 4 +++- .../hosting/kubernetes/kubernetes-production.md | 10 ++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/concepts/dapr-services/scheduler.md b/daprdocs/content/en/concepts/dapr-services/scheduler.md index 53fd0ddd19e..74638ffa491 100644 --- a/daprdocs/content/en/concepts/dapr-services/scheduler.md +++ b/daprdocs/content/en/concepts/dapr-services/scheduler.md @@ -19,7 +19,9 @@ The Scheduler service Docker container is started automatically as part of `dapr ## Kubernetes mode -The Scheduler service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. For more information on running Dapr on Kubernetes, visit the [Kubernetes hosting page]({{< ref kubernetes >}}). +The Scheduler service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. You can run Scheduler in high availability (HA) mode. [Learn more about setting HA mode in your Kubernetes service.]({{< ref "kubernetes-production.md#high-availability-mode" >}}) + +For more information on running Dapr on Kubernetes, visit the [Kubernetes hosting page]({{< ref kubernetes >}}). ## Related links diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md index 7a4cd1ec74c..16cb51674fa 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md +++ b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md @@ -148,7 +148,9 @@ If an invocation of the method fails, the timer is not removed. Timers are only ## Reminder data serialization format -Actor reminder data is serialized to JSON by default. Dapr v1.13 onwards supports a protobuf serialization format for reminders data which, depending on throughput and size of the payload, can result in significant performance improvements, giving developers a higher throughput and lower latency. Another benefit is storing smaller data in the actor underlying database, which can result in cost optimizations when using some cloud databases. A restriction with using protobuf serialization is that the reminder data can no longer be queried. +Actor reminder data is serialized to JSON by default. Dapr v1.13 onwards supports a protobuf serialization format for internal reminders data for workflow via both the Placement and Scheduler services. Depending on throughput and size of the payload, this can result in significant performance improvements, giving developers a higher throughput and lower latency. + +Another benefit is storing smaller data in the actor underlying database, which can result in cost optimizations when using some cloud databases. A restriction with using protobuf serialization is that the reminder data can no longer be queried. {{% alert title="Note" color="primary" %}} Protobuf serialization will become the default format in Dapr 1.14 diff --git a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md index 8e5ea993453..bdcd3ddcbeb 100644 --- a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md +++ b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md @@ -95,6 +95,16 @@ For a new Dapr deployment, HA mode can be set with both: For an existing Dapr deployment, [you can enable HA mode in a few extra steps]({{< ref "#enabling-high-availability-in-an-existing-dapr-deployment" >}}). +### Scheduler service HA configuration + +As of Dapr 1.15, the scheduler `dapr_scheduler.ha` flag scales schedulers to three instances independently of the `global.ha.enabled` flag. Default is one instance, meaning HA for schedulers is not default. + +`global.ha.enabled` set to `true` is fully respected and cannot be overridden by setting the local HA flag to `false`. + +To scale the schedulers to three instancers, set `global.ha.enabled` to false and `dapr_scheduler.ha` to true. + +This flag can be set via Helm with `--set dapr_scheduler.ha=true`. + ## Setting cluster critical priority class name for control plane services In some scenarios, nodes may have memory and/or cpu pressure and the Dapr control plane pods might get selected From 077b0520bed43a83fae658d36fb650e09bf82435 Mon Sep 17 00:00:00 2001 From: Elena Kolevska Date: Thu, 12 Dec 2024 22:37:37 +0000 Subject: [PATCH 19/31] Update docs for scheduler ephemeral storage (#4438) * Updates scheduler ephemeral storage docs Signed-off-by: Elena Kolevska * Update daprdocs/content/en/operations/hosting/kubernetes/kubernetes-persisting-scheduler.md Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Signed-off-by: Elena Kolevska * Apply suggestions from code review Co-authored-by: Mark Fussell Signed-off-by: Elena Kolevska --------- Signed-off-by: Elena Kolevska Signed-off-by: Elena Kolevska Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Co-authored-by: Mark Fussell --- .../hosting/kubernetes/kubernetes-persisting-scheduler.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-persisting-scheduler.md b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-persisting-scheduler.md index b4e8f02e64e..8c877d73c28 100644 --- a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-persisting-scheduler.md +++ b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-persisting-scheduler.md @@ -172,8 +172,8 @@ helm upgrade --install dapr dapr/dapr \ ## Ephemeral Storage -Scheduler can be optionally made to use Ephemeral storage, which is in-memory storage which is **not** resilient to restarts, i.e. all Job data will be lost after a Scheduler restart. -This is useful for deployments where storage is not available or required, or for testing purposes. +When running in non-HA mode, the Scheduler can be optionally made to use ephemeral storage, which is in-memory storage that is **not** resilient to restarts. For example, all jobs data is lost after a Scheduler restart. +This is useful in non-production deployments or for testing where storage is not available or required. {{% alert title="Note" color="primary" %}} If Dapr is already installed, the control plane needs to be completely [uninstalled]({{< ref dapr-uninstall.md >}}) in order for the Scheduler `StatefulSet` to be recreated without the persistent volume. From c13e6d9cc918fef42dca66ba3c074445a7899df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Cha=C3=ADn?= Date: Thu, 12 Dec 2024 23:38:16 +0100 Subject: [PATCH 20/31] Update setup-aws-snssqs.md (#4437) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update setup-aws-snssqs.md Add `concurrencyLimit` parameter description. Signed-off-by: Gustavo Chaín * Update daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Signed-off-by: Gustavo Chaín * Update setup-aws-snssqs.md Added # - name: concurrencyLimit into example Signed-off-by: Mark Fussell --------- Signed-off-by: Gustavo Chaín Signed-off-by: Mark Fussell Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Co-authored-by: Mark Fussell --- .../components-reference/supported-pubsub/setup-aws-snssqs.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md index 360bd6ef3e3..86865de5b30 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md @@ -68,7 +68,8 @@ spec: # value: 5 # - name: concurrencyMode # Optional # value: "single" - + # - name: concurrencyLimit # Optional + # value: "0" ``` @@ -98,6 +99,7 @@ The above example uses secrets as plain strings. It is recommended to use [a sec | disableDeleteOnRetryLimit | N | When set to true, after retrying and failing of `messageRetryLimit` times processing a message, reset the message visibility timeout so that other consumers can try processing, instead of deleting the message from SQS (the default behvior). Default: `"false"` | `"true"`, `"false"` | assetsManagementTimeoutSeconds | N | Amount of time in seconds, for an AWS asset management operation, before it times out and cancelled. Asset management operations are any operations performed on STS, SNS and SQS, except message publish and consume operations that implement the default Dapr component retry behavior. The value can be set to any non-negative float/integer. Default: `5` | `0.5`, `10` | concurrencyMode | N | When messages are received in bulk from SQS, call the subscriber sequentially (“single” message at a time), or concurrently (in “parallel”). Default: `"parallel"` | `"single"`, `"parallel"` +| concurrencyLimit | N | Defines the maximum number of concurrent workers handling messages. This value is ignored when concurrencyMode is set to `"single"`. To avoid limiting the number of concurrent workers, set this to `0`. Default: `0` | `100` ### Additional info From 90c9d81a25ffd69c57cdb377f044ee2f11292d59 Mon Sep 17 00:00:00 2001 From: Anton Troshin Date: Thu, 12 Dec 2024 19:51:12 -0600 Subject: [PATCH 21/31] Fix resiliency example typo Signed-off-by: Anton Troshin --- daprdocs/content/en/operations/resiliency/policies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/resiliency/policies.md b/daprdocs/content/en/operations/resiliency/policies.md index d394039d576..c7b40c3b88f 100644 --- a/daprdocs/content/en/operations/resiliency/policies.md +++ b/daprdocs/content/en/operations/resiliency/policies.md @@ -96,7 +96,7 @@ spec: policy: constant duration: 5s maxRetries: 3 - matches: + matching: httpStatusCodes: "429,500-599" # retry the HTTP status codes in this range. All others are not retried. gRPCStatusCodes: "1-4,8-11,13,14" # retry gRPC status codes in these ranges and separate single codes. ``` From a3ebf07b94647a9e3777d3a37ad652469b69fad7 Mon Sep 17 00:00:00 2001 From: Jake Engelberg <152900222+jake-engelberg@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:39:53 -0500 Subject: [PATCH 22/31] Building Block -> API Co-authored-by: Mark Fussell Signed-off-by: Jake Engelberg <152900222+jake-engelberg@users.noreply.github.com> --- .../content/en/reference/api/error_codes.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/daprdocs/content/en/reference/api/error_codes.md b/daprdocs/content/en/reference/api/error_codes.md index 2e18882aa07..c098521ccb5 100644 --- a/daprdocs/content/en/reference/api/error_codes.md +++ b/daprdocs/content/en/reference/api/error_codes.md @@ -17,7 +17,7 @@ For http calls made to Dapr runtime, when an error is encountered, an error json The following tables list the error codes returned by Dapr runtime: -### Actors (Building Block) +### Actors API | Error Code | Description | | -------------------------------- | ------------------------------------------ | @@ -34,7 +34,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_ACTOR_STATE_TRANSACTION_SAVE | Error storing actor state transactionally. | | ERR_ACTOR_REMINDER_NON_HOSTED | Error setting reminder for an actor. | -### Workflows (Building Block) +### Workflows API | Error Code | Description | | -------------------------------- | ----------------------------------------------------------- | @@ -54,7 +54,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_INSTANCE_ID_PROVIDED_MISSING | Error workflow instance ID was provided but missing. | | ERR_INSTANCE_ID_TOO_LONG | Error workflow instance ID exceeds allowable length. | -### State Management (Building Block) +### State Management API | Error Code | Description | | ------------------------------------- | ------------------------------------------------------------------------- | @@ -71,7 +71,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_STATE_STORE_NOT_SUPPORTED | Error state store is not supported. | | ERR_STATE_STORE_TOO_MANY_TRANSACTIONS | Error exceeded maximum allowable transactions. | -### Configuration (Building Block) +### Configuration API | Error Code | Description | | -------------------------------------- | -------------------------------------------- | @@ -81,7 +81,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_CONFIGURATION_SUBSCRIBE | Error subscribing to a configuration. | | ERR_CONFIGURATION_UNSUBSCRIBE | Error unsubscribing from a configuration. | -### Crypto (Building Block) +### Crypto API | Error Code | Description | | ----------------------------------- | ------------------------------------------ | @@ -90,7 +90,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_CRYPTO_PROVIDER_NOT_FOUND | Error specified crypto provider not found. | | ERR_CRYPTO_PROVIDERS_NOT_CONFIGURED | Error no crypto providers configured. | -### Secrets (Building Block) +### Secrets API | Error Code | Description | | -------------------------------- | ---------------------------------------------------- | @@ -99,7 +99,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_SECRET_GET | Error retrieving the specified secret. | | ERR_PERMISSION_DENIED | Error access denied due to insufficient permissions. | -### Pub/Sub (Building Block) +### Pub/Sub API | Error Code | Description | | --------------------------- | -------------------------------------------------------- | @@ -114,7 +114,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_PUBLISH_OUTBOX | Error publishing message to the outbox. | | ERR_TOPIC_NAME_EMPTY | Error topic name for Pub/Sub message is empty. | -### Conversation (Building Block) +### Conversation API | Error Code | Description | | ------------------------------- | ----------------------------------------------- | @@ -125,7 +125,7 @@ The following tables list the error codes returned by Dapr runtime: | ERR_CONVERSATION_MISSING_INPUTS | Error missing required inputs for conversation. | | ERR_CONVERSATION_NOT_FOUND | Error conversation not found. | -### Distributed Lock (Building Block) +### Distributed Lock API | Error Code | Description | | ----------------------------- | ----------------------------------- | From 9006331455b29e2074f020ed5de8436a485e4c83 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Fri, 13 Dec 2024 11:04:50 -0500 Subject: [PATCH 23/31] review from Mark and Cassie pt 2 Signed-off-by: Hannah Hunter --- .../en/concepts/dapr-services/placement.md | 4 +++- .../en/concepts/dapr-services/scheduler.md | 8 ++++++-- .../actors/actors-timers-reminders.md | 4 ++++ .../building-blocks/jobs/jobs-overview.md | 8 -------- .../hosting/kubernetes/kubernetes-deploy.md | 13 +++++++++++++ .../kubernetes/kubernetes-production.md | 19 ++++++++++++++----- .../support/support-preview-features.md | 2 +- 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/daprdocs/content/en/concepts/dapr-services/placement.md b/daprdocs/content/en/concepts/dapr-services/placement.md index d94f9a8435d..c6d739957f5 100644 --- a/daprdocs/content/en/concepts/dapr-services/placement.md +++ b/daprdocs/content/en/concepts/dapr-services/placement.md @@ -13,7 +13,9 @@ The Placement service Docker container is started automatically as part of [`dap ## Kubernetes mode -The Placement service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. For more information on running Dapr on Kubernetes, visit the [Kubernetes hosting page]({{< ref kubernetes >}}). +The Placement service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. You can run Placement in high availability (HA) mode. [Learn more about setting HA mode in your Kubernetes service.]({{< ref "kubernetes-production.md#individual-service-ha-helm-configuration" >}}) + +For more information on running Dapr on Kubernetes, visit the [Kubernetes hosting page]({{< ref kubernetes >}}). ## Placement tables diff --git a/daprdocs/content/en/concepts/dapr-services/scheduler.md b/daprdocs/content/en/concepts/dapr-services/scheduler.md index 74638ffa491..fd9f2f705a5 100644 --- a/daprdocs/content/en/concepts/dapr-services/scheduler.md +++ b/daprdocs/content/en/concepts/dapr-services/scheduler.md @@ -11,7 +11,11 @@ The diagram below shows how the Scheduler service is used via the jobs API when Diagram showing the Scheduler control plane service and the jobs API -The Scheduler service is used by default for [actor scheduler reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) where actor reminders, which are also used by workflows, are stored in the Scheduler service as opposed to the Placement service. +## Actor reminders + +Prior to Dapr v1.15, [actor reminders]({{< ref "actors-timers-reminders.md#actor-reminders" >}}) were run using the Placement service. Now, by default, the [`SchedulerReminders` feature flag]({{< ref "support-preview-features.md#current-preview-features" >}}) is set to `true`, and all new actor reminders you create are run using the Scheduler service to make them more scalable. + +Once you deploy Dapr v1.15, any _existing_ actor reminders are migrated from the Placement service to the Scheduler service. You can prevent this migration by setting the `SchedulerReminders` flag to `false`. ## Self-hosted mode @@ -19,7 +23,7 @@ The Scheduler service Docker container is started automatically as part of `dapr ## Kubernetes mode -The Scheduler service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. You can run Scheduler in high availability (HA) mode. [Learn more about setting HA mode in your Kubernetes service.]({{< ref "kubernetes-production.md#high-availability-mode" >}}) +The Scheduler service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. You can run Scheduler in high availability (HA) mode. [Learn more about setting HA mode in your Kubernetes service.]({{< ref "kubernetes-production.md#individual-service-ha-helm-configuration" >}}) For more information on running Dapr on Kubernetes, visit the [Kubernetes hosting page]({{< ref kubernetes >}}). diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md index 16cb51674fa..8664045632c 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md +++ b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md @@ -107,6 +107,10 @@ Refer [api spec]({{< ref "actors_api.md#invoke-timer" >}}) for more details. ## Actor reminders +{{% alert title="Note" color="primary" %}} +In Dapr v1.15, actor reminders are stored by default in the [Scheduler service]({{< ref "scheduler.md#actor-reminders" >}}). +{{% /alert %}} + 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 as shown below, or via Dapr SDK. diff --git a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md index facae8de2f6..63f90c102f6 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md +++ b/daprdocs/content/en/developing-applications/building-blocks/jobs/jobs-overview.md @@ -59,14 +59,6 @@ The jobs API provides several features to make it easy for you to schedule jobs. The Scheduler service enables the scheduling of jobs to scale across multiple replicas, while guaranteeing that a job is only triggered by 1 scheduler service instance. -### Actor reminders - -Actors have reminders; the Scheduler service is used by default for actor reminders (which are also used by workflows) to make them more scalable. - -> **Note:** In earlier releases, the Placement service was used for actor reminders. This is no longer recommended. - -The `SchedulerReminders` preview feature defaults to `true`. To disable actor scheduler reminders, you can set it to `false`. - ## Try out the jobs API You can try out the jobs API in your application. After [Dapr is installed]({{< ref install-dapr-cli.md >}}), you can begin using the jobs API, starting with [the How-to: Schedule jobs guide]({{< ref howto-schedule-and-handle-triggered-jobs.md >}}). diff --git a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md index 658d1475e5a..41af7c0d84a 100644 --- a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md +++ b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md @@ -231,6 +231,19 @@ You can install Dapr on Kubernetes using a Helm v3 chart. --wait ``` + To install in **high availability** mode and scale select services independently of global: + + ```bash + helm upgrade --install dapr dapr/dapr \ + --version={{% dapr-latest-version short="true" %}} \ + --namespace dapr-system \ + --create-namespace \ + --set global.ha.enabled=false \ + --set dapr_scheduler.ha=true \ + --set dapr_placement.ha=true \ + --wait + ``` + See [Guidelines for production ready deployments on Kubernetes]({{< ref kubernetes-production.md >}}) for more information on installing and upgrading Dapr using Helm. ### (optional) Install the Dapr dashboard as part of the control plane diff --git a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md index bdcd3ddcbeb..1151137efab 100644 --- a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md +++ b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-production.md @@ -95,15 +95,24 @@ For a new Dapr deployment, HA mode can be set with both: For an existing Dapr deployment, [you can enable HA mode in a few extra steps]({{< ref "#enabling-high-availability-in-an-existing-dapr-deployment" >}}). -### Scheduler service HA configuration +### Individual service HA Helm configuration -As of Dapr 1.15, the scheduler `dapr_scheduler.ha` flag scales schedulers to three instances independently of the `global.ha.enabled` flag. Default is one instance, meaning HA for schedulers is not default. +You can configure HA mode via Helm across all services by setting the `global.ha.enabled` flag to `true`. By default, `--set global.ha.enabled=true` is fully respected and cannot be overridden, making it impossible to simultaneously have either the placement or scheduler service as a single instance. -`global.ha.enabled` set to `true` is fully respected and cannot be overridden by setting the local HA flag to `false`. +> **Note:** HA for scheduler and placement services is not the default setting. -To scale the schedulers to three instancers, set `global.ha.enabled` to false and `dapr_scheduler.ha` to true. +To scale scheduler and placement to three instances independently of the `global.ha.enabled` flag, set `global.ha.enabled` to `false` and `dapr_scheduler.ha` and `dapr_placement.ha` to `true`. For example: -This flag can be set via Helm with `--set dapr_scheduler.ha=true`. + ```bash + helm upgrade --install dapr dapr/dapr \ + --version={{% dapr-latest-version short="true" %}} \ + --namespace dapr-system \ + --create-namespace \ + --set global.ha.enabled=false \ + --set dapr_scheduler.ha=true \ + --set dapr_placement.ha=true \ + --wait + ``` ## Setting cluster critical priority class name for control plane services diff --git a/daprdocs/content/en/operations/support/support-preview-features.md b/daprdocs/content/en/operations/support/support-preview-features.md index 88c00f6492a..07ae1b9a679 100644 --- a/daprdocs/content/en/operations/support/support-preview-features.md +++ b/daprdocs/content/en/operations/support/support-preview-features.md @@ -22,4 +22,4 @@ For CLI there is no explicit opt-in, just the version that this was first made a | **Actor State TTL** | Allow actors to save records to state stores with Time To Live (TTL) set to automatically clean up old data. In its current implementation, actor state with TTL may not be reflected correctly by clients, read [Actor State Transactions]({{< ref actors_api.md >}}) for more information. | `ActorStateTTL` | [Actor State Transactions]({{< ref actors_api.md >}}) | v1.11 | | **Component Hot Reloading** | Allows for Dapr-loaded components to be "hot reloaded". A component spec is reloaded when it is created/updated/deleted in Kubernetes or on file when running in self-hosted mode. Ignores changes to actor state stores and workflow backends. | `HotReload`| [Hot Reloading]({{< ref components-concept.md >}}) | v1.13 | | **Subscription Hot Reloading** | Allows for declarative subscriptions to be "hot reloaded". A subscription is reloaded either when it is created/updated/deleted in Kubernetes, or on file in self-hosted mode. In-flight messages are unaffected when reloading. | `HotReload`| [Hot Reloading]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | v1.14 | -| **Scheduler Actor Reminders** | Scheduler actor reminders are actor reminders stored in the Scheduler control plane service, as opposed to the Placement control plane service actor reminder system. The `SchedulerReminders` preview feature defaults to `true`, but you can disable Scheduler actor reminders by setting it to `false`. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "jobs-overview.md#actor-reminders" >}}) | v1.14 | \ No newline at end of file +| **Scheduler Actor Reminders** | Scheduler actor reminders are actor reminders stored in the Scheduler control plane service, as opposed to the Placement control plane service actor reminder system. The `SchedulerReminders` preview feature defaults to `true`, but you can disable Scheduler actor reminders by setting it to `false`. | `SchedulerReminders`| [Scheduler actor reminders]({{< ref "scheduler.md#actor-reminders" >}}) | v1.14 | \ No newline at end of file From 263db693ecd2f4e16e32a32c2d40cb833e0ce966 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Fri, 13 Dec 2024 12:18:39 -0500 Subject: [PATCH 24/31] create new errors topic Signed-off-by: Hannah Hunter --- .../debugging/_index.md | 2 +- .../develop-components/_index.md | 2 +- .../error-codes/_index.md | 8 +++++++ .../error-codes/error-codes-reference.md} | 22 ++++++++----------- .../error-codes/errors-overview.md | 13 +++++++++++ .../error-codes/grpc-error-codes.md} | 14 +++++------- .../error-codes/http-error-codes.md | 21 ++++++++++++++++++ .../integrations/_index.md | 2 +- .../local-development/_index.md | 2 +- .../en/developing-applications/sdks/_index.md | 2 +- 10 files changed, 62 insertions(+), 26 deletions(-) create mode 100644 daprdocs/content/en/developing-applications/error-codes/_index.md rename daprdocs/content/en/{reference/api/error_codes.md => developing-applications/error-codes/error-codes-reference.md} (95%) create mode 100644 daprdocs/content/en/developing-applications/error-codes/errors-overview.md rename daprdocs/content/en/{reference/errors/_index.md => developing-applications/error-codes/grpc-error-codes.md} (93%) create mode 100644 daprdocs/content/en/developing-applications/error-codes/http-error-codes.md diff --git a/daprdocs/content/en/developing-applications/debugging/_index.md b/daprdocs/content/en/developing-applications/debugging/_index.md index bb9d76df122..d6d77e77df1 100644 --- a/daprdocs/content/en/developing-applications/debugging/_index.md +++ b/daprdocs/content/en/developing-applications/debugging/_index.md @@ -2,6 +2,6 @@ type: docs title: "Debugging Dapr applications and the Dapr control plane" linkTitle: "Debugging" -weight: 50 +weight: 60 description: "Guides on how to debug Dapr applications and the Dapr control plane" --- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/develop-components/_index.md b/daprdocs/content/en/developing-applications/develop-components/_index.md index cb9f7e8a851..970744958fc 100644 --- a/daprdocs/content/en/developing-applications/develop-components/_index.md +++ b/daprdocs/content/en/developing-applications/develop-components/_index.md @@ -2,6 +2,6 @@ type: docs title: "Components" linkTitle: "Components" -weight: 30 +weight: 40 description: "Learn more about developing Dapr's pluggable and middleware components" --- diff --git a/daprdocs/content/en/developing-applications/error-codes/_index.md b/daprdocs/content/en/developing-applications/error-codes/_index.md new file mode 100644 index 00000000000..f693722f5a6 --- /dev/null +++ b/daprdocs/content/en/developing-applications/error-codes/_index.md @@ -0,0 +1,8 @@ +--- +type: docs +title: "Error codes" +linkTitle: "Error codes" +weight: 20 +description: "Error codes and messages you may encounter while using Dapr" +--- + diff --git a/daprdocs/content/en/reference/api/error_codes.md b/daprdocs/content/en/developing-applications/error-codes/error-codes-reference.md similarity index 95% rename from daprdocs/content/en/reference/api/error_codes.md rename to daprdocs/content/en/developing-applications/error-codes/error-codes-reference.md index c098521ccb5..314bf67c4d7 100644 --- a/daprdocs/content/en/reference/api/error_codes.md +++ b/daprdocs/content/en/developing-applications/error-codes/error-codes-reference.md @@ -1,20 +1,11 @@ --- type: docs -title: "Error codes returned by APIs" -linkTitle: "Error codes" -description: "Detailed reference of the Dapr API error codes" -weight: 1400 +title: "Error codes reference guide" +linkTitle: "Reference" +description: "List of gRPC and HTTP error codes in Dapr and their descriptions" +weight: 20 --- -For http calls made to Dapr runtime, when an error is encountered, an error json is returned in http response body. The json contains an error code and an descriptive error message, e.g. - -``` -{ - "errorCode": "ERR_STATE_GET", - "message": "Requested state key does not exist in state store." -} -``` - The following tables list the error codes returned by Dapr runtime: ### Actors API @@ -154,3 +145,8 @@ The following tables list the error codes returned by Dapr runtime: | ERR_MALFORMED_REQUEST | Error with a malformed request. | | ERR_MALFORMED_REQUEST_DATA | Error request data is malformed. | | ERR_MALFORMED_RESPONSE | Error response data is malformed. | + +## Next steps + +- [Handling HTTP error codes]({{< ref http-error-codes.md >}}) +- [Handling gRPC error codes]({{< ref grpc-error-codes.md >}}) \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/error-codes/errors-overview.md b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md new file mode 100644 index 00000000000..5f34aff4dde --- /dev/null +++ b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md @@ -0,0 +1,13 @@ +--- +type: docs +title: "Errors overview" +linkTitle: "Overview" +weight: 10 +description: "Overview of Dapr errors" +--- + + + +## Next step + +{{< button text="Error code reference" page="error-codes-reference" >}} diff --git a/daprdocs/content/en/reference/errors/_index.md b/daprdocs/content/en/developing-applications/error-codes/grpc-error-codes.md similarity index 93% rename from daprdocs/content/en/reference/errors/_index.md rename to daprdocs/content/en/developing-applications/error-codes/grpc-error-codes.md index 35f685f7491..1d343cce59d 100644 --- a/daprdocs/content/en/reference/errors/_index.md +++ b/daprdocs/content/en/developing-applications/error-codes/grpc-error-codes.md @@ -1,20 +1,18 @@ --- type: docs -title: Dapr errors -linkTitle: "Dapr errors" -weight: 700 -description: "Information on Dapr errors and how to handle them" +title: Handling gRPC error codes +linkTitle: "gRPC" +weight: 40 +description: "Information on Dapr gRPC errors and how to handle them" --- -## Error handling: Understanding errors model and reporting - Initially, errors followed the [Standard gRPC error model](https://grpc.io/docs/guides/error/#standard-error-model). However, to provide more detailed and informative error messages, an enhanced error model has been defined which aligns with the gRPC [Richer error model](https://grpc.io/docs/guides/error/#richer-error-model). {{% alert title="Note" color="primary" %}} Not all Dapr errors have been converted to the richer gRPC error model. {{% /alert %}} -### Standard gRPC Error Model +## Standard gRPC Error Model The [Standard gRPC error model](https://grpc.io/docs/guides/error/#standard-error-model) is an approach to error reporting in gRPC. Each error response includes an error code and an error message. The error codes are standardized and reflect common error conditions. @@ -25,7 +23,7 @@ ERROR: Message: input key/keyPrefix 'bad||keyname' can't contain '||' ``` -### Richer gRPC Error Model +## Richer gRPC Error Model The [Richer gRPC error model](https://grpc.io/docs/guides/error/#richer-error-model) extends the standard error model by providing additional context and details about the error. This model includes the standard error `code` and `message`, along with a `details` section that can contain various types of information, such as `ErrorInfo`, `ResourceInfo`, and `BadRequest` details. diff --git a/daprdocs/content/en/developing-applications/error-codes/http-error-codes.md b/daprdocs/content/en/developing-applications/error-codes/http-error-codes.md new file mode 100644 index 00000000000..c05a0dac854 --- /dev/null +++ b/daprdocs/content/en/developing-applications/error-codes/http-error-codes.md @@ -0,0 +1,21 @@ +--- +type: docs +title: "Handling HTTP error codes" +linkTitle: "HTTP" +description: "Detailed reference of the Dapr HTTP error codes and how to handle them" +weight: 30 +--- + +For http calls made to Dapr runtime, when an error is encountered, an error json is returned in http response body. The json contains an error code and an descriptive error message, e.g. + +``` +{ + "errorCode": "ERR_STATE_GET", + "message": "Requested state key does not exist in state store." +} +``` + +## Related + +- [Error code reference list]({{< ref error-codes-reference.md >}}) +- [Handling gRPC error codes]({{< ref grpc-error-codes.md >}}) \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/integrations/_index.md b/daprdocs/content/en/developing-applications/integrations/_index.md index a884aeb5c43..b988581b78b 100644 --- a/daprdocs/content/en/developing-applications/integrations/_index.md +++ b/daprdocs/content/en/developing-applications/integrations/_index.md @@ -2,6 +2,6 @@ type: docs title: "Integrations" linkTitle: "Integrations" -weight: 60 +weight: 70 description: "Dapr integrations with other technologies" --- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/local-development/_index.md b/daprdocs/content/en/developing-applications/local-development/_index.md index b06587df577..8ffc396d4ee 100644 --- a/daprdocs/content/en/developing-applications/local-development/_index.md +++ b/daprdocs/content/en/developing-applications/local-development/_index.md @@ -2,6 +2,6 @@ type: docs title: "Local development" linkTitle: "Local development" -weight: 40 +weight: 50 description: "Capabilities for developing Dapr applications locally" --- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/sdks/_index.md b/daprdocs/content/en/developing-applications/sdks/_index.md index 4f56c0513bd..5434d497b26 100644 --- a/daprdocs/content/en/developing-applications/sdks/_index.md +++ b/daprdocs/content/en/developing-applications/sdks/_index.md @@ -2,7 +2,7 @@ type: docs title: "Dapr Software Development Kits (SDKs)" linkTitle: "SDKs" -weight: 20 +weight: 30 description: "Use your favorite languages with Dapr" no_list: true --- From 5378f783baaa2f50d24dfcb7ddd14eed3b1acfa4 Mon Sep 17 00:00:00 2001 From: Anton Troshin Date: Fri, 13 Dec 2024 11:57:55 -0600 Subject: [PATCH 25/31] Add retry status codes to schema doc Signed-off-by: Anton Troshin --- .../content/en/reference/resource-specs/resiliency-schema.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md index 06733d1d827..d307b70b4d4 100644 --- a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md +++ b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md @@ -32,6 +32,9 @@ spec: duration: maxInterval: maxRetries: + matching: + httpStatusCodes: + gRPCStatusCodes: circuitBreakers: circuitBreakerName: # Replace with any unique name maxRequests: From 78f427d95d6844b52f6c2d29a9446ae98d6c7e13 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Fri, 13 Dec 2024 15:13:44 -0500 Subject: [PATCH 26/31] overview draft Signed-off-by: Hannah Hunter --- .../error-codes/errors-overview.md | 51 ++++++++++++++++++- .../configuration/configuration-overview.md | 5 +- .../observability/metrics/metrics-overview.md | 2 +- .../resource-specs/configuration-schema.md | 1 + 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/developing-applications/error-codes/errors-overview.md b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md index 5f34aff4dde..f007a411a91 100644 --- a/daprdocs/content/en/developing-applications/error-codes/errors-overview.md +++ b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md @@ -6,8 +6,57 @@ weight: 10 description: "Overview of Dapr errors" --- +An error code is a numeric or alphamueric code that indicates the nature of an error and, when possible, why it occured. +Dapr error codes are standardized strings for over 80+ common errors across HTTP and gRPC requests when using the Dapr APIs. These codes are both: +- Returned in the JSON response body of the request +- When enabled, logged in debug-level logs in the runtime. + - If you're running in Kubernetes, error codes are logged in the sidecar. + - If you're running in self-hosted, you can enable and run debug logs. + +## Error format + +Dapr error codes consist of a prefix, a category, and shorthand of the error itself. For example: + +| Prefix | Category | Error shorthand | +| ------ | -------- | --------------- | +| ERR_ | PUBSUB_ | NOT_FOUND | + +Some of the most common errors returned include: + +- ERR_ACTOR_TIMER_CREATE +- ERR_PURGE_WORKFLOW +- ERR_STATE_STORE_NOT_FOUND +- ERR_HEALTH_NOT_READY + +> **Note:** [See a full list of error codes in Dapr.]({{< ref error-codes-reference.md >}}) + +An error returned for a state store not found might look like the following: + +```json +{ + "error": "Bad Request", + "error_msg": "{\"errorCode\":\"ERR_STATE_STORE_NOT_FOUND\",\"message\":\"state store is not found\",\"details\":[{\"@type\":\"type.googleapis.com/google.rpc.ErrorInfo\",\"domain\":\"dapr.io\",\"metadata\":{\"appID\":\"nodeapp\"},\"reason\":\"DAPR_STATE_NOT_FOUND\"}]}", + "status": 400 +} +``` + +The returned error includes: +- The error code: `ERR_STATE_STORE_NOT_FOUND` +- The error message describing the issue: `state store is not found` +- The app ID in which the error is occuring: `nodeapp` +- The reason for the error: `DAPR_STATE_NOT_FOUND` + +## Dapr error code metrics + +Metrics help users see when exactly errors are occuring from within the runtime. Error code metrics are collected using the `error_code_total` endpoint. This endpoint is disabled by default. You can [enable it using the `recordErrorCodes` field in your configuration file]({{< ref "metrics-overview.md#configuring-metrics-for-error-codes" >}}). + +## Demo + +Watch a demo presented during [Diagrid's Dapr v1.15 celebration](https://www.diagrid.io/videos/dapr-1-15-deep-dive) to see how to enable error code metrics and handle error codes returned in the runtime. + + ## Next step -{{< button text="Error code reference" page="error-codes-reference" >}} +{{< button text="See a list of all Dapr error codes" page="error-codes-reference" >}} \ No newline at end of file diff --git a/daprdocs/content/en/operations/configuration/configuration-overview.md b/daprdocs/content/en/operations/configuration/configuration-overview.md index 7225fc11f2f..5a528a22433 100644 --- a/daprdocs/content/en/operations/configuration/configuration-overview.md +++ b/daprdocs/content/en/operations/configuration/configuration-overview.md @@ -145,9 +145,12 @@ metrics: - /payments/{paymentID}/refund - /payments/{paymentID}/details excludeVerbs: false + recordErrorCodes: true ``` -In the examples above, the path filter `/orders/{orderID}/items/{itemID}` would return _a single metric count_ matching all the `orderID`s and all the `itemID`s, rather than multiple metrics for each `itemID`. For more information, see [HTTP metrics path matching]({{< ref "metrics-overview.md#http-metrics-path-matching" >}}) +In the examples above, the path filter `/orders/{orderID}/items/{itemID}` would return _a single metric count_ matching all the `orderID`s and all the `itemID`s, rather than multiple metrics for each `itemID`. For more information, see [HTTP metrics path matching]({{< ref "metrics-overview.md#http-metrics-path-matching" >}}). + +The above example also enables [recording error code metrics]({{< ref "metrics-overview.md#configuring-metrics-for-error-codes" >}}), which is disabled by default. The following table lists the properties for metrics: diff --git a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md index 23fea29e6db..1df663ab705 100644 --- a/daprdocs/content/en/operations/observability/metrics/metrics-overview.md +++ b/daprdocs/content/en/operations/observability/metrics/metrics-overview.md @@ -72,7 +72,7 @@ spec: ## Configuring metrics for error codes -You can enable additional metrics for [Dapr API error codes](https://docs.dapr.io/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. Dapr APIs which communicate back to their caller may return standardized error codes. As described in the [Dapr development docs](https://github.com/dapr/dapr/blob/master/docs/development/dapr-metrics.md), a new metric called `error_code_total` is recorded, which allows monitoring of error codes triggered by application, code, and category. See [the `errorcodes` package](https://github.com/dapr/dapr/blob/master/pkg/messages/errorcodes/errorcodes.go) for specific codes and categories. +You can enable additional metrics for [Dapr API error codes](https://docs.dapr.io/reference/api/error_codes/) by setting `spec.metrics.recordErrorCodes` to `true`. Dapr APIs which communicate back to their caller may return standardized error codes. [A new metric called `error_code_total` is recorded]({{< ref errors-overview.md >}}), which allows monitoring of error codes triggered by application, code, and category. See [the `errorcodes` package](https://github.com/dapr/dapr/blob/master/pkg/messages/errorcodes/errorcodes.go) for specific codes and categories. Example configuration: ```yaml diff --git a/daprdocs/content/en/reference/resource-specs/configuration-schema.md b/daprdocs/content/en/reference/resource-specs/configuration-schema.md index b52228c16cf..e5caac79219 100644 --- a/daprdocs/content/en/reference/resource-specs/configuration-schema.md +++ b/daprdocs/content/en/reference/resource-specs/configuration-schema.md @@ -36,6 +36,7 @@ spec: labels: - name: regex: {} + recordErrorCodes: latencyDistributionBuckets: - - From 87c854e59ee82ebd4487b2802282829cd51a3e31 Mon Sep 17 00:00:00 2001 From: Elena Kolevska Date: Tue, 17 Dec 2024 19:17:23 +0000 Subject: [PATCH 27/31] Updates python version and setup-python action in link validation GH action (#4470) Signed-off-by: Elena Kolevska --- .github/workflows/link_validation.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/link_validation.yaml b/.github/workflows/link_validation.yaml index 4b7840e3cb1..350f8407a33 100644 --- a/.github/workflows/link_validation.yaml +++ b/.github/workflows/link_validation.yaml @@ -13,7 +13,7 @@ jobs: validate: runs-on: ubuntu-latest env: - PYTHON_VER: 3.7 + PYTHON_VER: 3.12 steps: - uses: actions/checkout@v2 - name: Check Microsoft URLs do not pin localized versions @@ -27,7 +27,7 @@ jobs: exit 1 fi - name: Set up Python ${{ env.PYTHON_VER }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VER }} - name: Install dependencies From cd8a62467f5d2bccc0ab4e26e8b41f30bf13d641 Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Wed, 18 Dec 2024 12:09:38 -0500 Subject: [PATCH 28/31] Update daprdocs/content/en/concepts/dapr-services/scheduler.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --- daprdocs/content/en/concepts/dapr-services/scheduler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/concepts/dapr-services/scheduler.md b/daprdocs/content/en/concepts/dapr-services/scheduler.md index fd9f2f705a5..2fba4ba713a 100644 --- a/daprdocs/content/en/concepts/dapr-services/scheduler.md +++ b/daprdocs/content/en/concepts/dapr-services/scheduler.md @@ -15,7 +15,7 @@ The diagram below shows how the Scheduler service is used via the jobs API when Prior to Dapr v1.15, [actor reminders]({{< ref "actors-timers-reminders.md#actor-reminders" >}}) were run using the Placement service. Now, by default, the [`SchedulerReminders` feature flag]({{< ref "support-preview-features.md#current-preview-features" >}}) is set to `true`, and all new actor reminders you create are run using the Scheduler service to make them more scalable. -Once you deploy Dapr v1.15, any _existing_ actor reminders are migrated from the Placement service to the Scheduler service. You can prevent this migration by setting the `SchedulerReminders` flag to `false`. +When you deploy Dapr v1.15, any _existing_ actor reminders are migrated from the Placement service to the Scheduler service as a one time operation for each actor type. You can prevent this migration by setting the `SchedulerReminders` flag to `false` in application configuration file for the actor type. ## Self-hosted mode From abc1f553fcbc8e56b23f734870eae82432267fe5 Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:44:39 -0500 Subject: [PATCH 29/31] Update daprdocs/content/en/developing-applications/error-codes/errors-overview.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --- .../en/developing-applications/error-codes/errors-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/error-codes/errors-overview.md b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md index f007a411a91..7b654b447ad 100644 --- a/daprdocs/content/en/developing-applications/error-codes/errors-overview.md +++ b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md @@ -9,7 +9,7 @@ description: "Overview of Dapr errors" An error code is a numeric or alphamueric code that indicates the nature of an error and, when possible, why it occured. Dapr error codes are standardized strings for over 80+ common errors across HTTP and gRPC requests when using the Dapr APIs. These codes are both: -- Returned in the JSON response body of the request +- Returned in the JSON response body of the request. - When enabled, logged in debug-level logs in the runtime. - If you're running in Kubernetes, error codes are logged in the sidecar. - If you're running in self-hosted, you can enable and run debug logs. From a5c2936b58a2287bdb7eac515f2c88223b07c993 Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:44:46 -0500 Subject: [PATCH 30/31] Update daprdocs/content/en/developing-applications/error-codes/errors-overview.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --- .../en/developing-applications/error-codes/errors-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/error-codes/errors-overview.md b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md index 7b654b447ad..762413fb7f7 100644 --- a/daprdocs/content/en/developing-applications/error-codes/errors-overview.md +++ b/daprdocs/content/en/developing-applications/error-codes/errors-overview.md @@ -49,7 +49,7 @@ The returned error includes: ## Dapr error code metrics -Metrics help users see when exactly errors are occuring from within the runtime. Error code metrics are collected using the `error_code_total` endpoint. This endpoint is disabled by default. You can [enable it using the `recordErrorCodes` field in your configuration file]({{< ref "metrics-overview.md#configuring-metrics-for-error-codes" >}}). +Metrics help you see when exactly errors are occuring from within the runtime. Error code metrics are collected using the `error_code_total` endpoint. This endpoint is disabled by default. You can [enable it using the `recordErrorCodes` field in your configuration file]({{< ref "metrics-overview.md#configuring-metrics-for-error-codes" >}}). ## Demo From 9006404987ef008014e03da1b873f75e37054225 Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:44:55 -0500 Subject: [PATCH 31/31] Update daprdocs/content/en/developing-applications/error-codes/http-error-codes.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --- .../en/developing-applications/error-codes/http-error-codes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/error-codes/http-error-codes.md b/daprdocs/content/en/developing-applications/error-codes/http-error-codes.md index c05a0dac854..1b069ebaf9d 100644 --- a/daprdocs/content/en/developing-applications/error-codes/http-error-codes.md +++ b/daprdocs/content/en/developing-applications/error-codes/http-error-codes.md @@ -6,7 +6,7 @@ description: "Detailed reference of the Dapr HTTP error codes and how to handle weight: 30 --- -For http calls made to Dapr runtime, when an error is encountered, an error json is returned in http response body. The json contains an error code and an descriptive error message, e.g. +For HTTP calls made to Dapr runtime, when an error is encountered, an error JSON is returned in response body. The JSON contains an error code and an descriptive error message. ``` {