diff --git a/docs/docs/administration/cli.mdx b/docs/docs/administration/cli.mdx index 3fef835e3dca..10bc4a3dcdfd 100644 --- a/docs/docs/administration/cli.mdx +++ b/docs/docs/administration/cli.mdx @@ -6,7 +6,7 @@ description: Overview of the Dispatch CLI. Dispatch ships with a robust CLI, providing configuration, server, scheduler, plugin, database, and shell commands. Here we'll give a partial overview; if you'd like a complete list of Dispatch commands available via the CLI, please use the command `dispatch --help` once you have installed the application. -## Server +## Server {#server} The server sub-command contains all Dispatch server-related commands. @@ -27,7 +27,7 @@ Commands: start ``` -### Config +### Config {#config} The `config` command helps debug as it shows the configuration variables seen by the server \(combining envvars, defaults, and the .env file\). @@ -42,7 +42,7 @@ METRIC_PROVIDERS spectator-metric ... ``` -### Develop +### Develop {#develop} The `develop` command starts the development server. This server will continually watch for file changes and reload the server accordingly. You'll find it useful to combine this with a `DEBUG` log level, as below. @@ -50,7 +50,7 @@ The `develop` command starts the development server. This server will continuall > dispatch server develop --log-level debug ``` -### Routes +### Routes {#routes} The `routes` command is useful for development. This command shows which endpoints the server is currently listening on, the HTTP verb methods are accepted, and whether authentication is enabled. @@ -65,7 +65,7 @@ Path Authenticated Methods ... ``` -### Shell +### Shell {#shell} The `shell` command is useful for development. It drops you into an interactive python shell with the same context as the server itself. @@ -73,7 +73,7 @@ The `shell` command is useful for development. It drops you into an interactive > dispatch server shell ``` -### Start +### Start {#start} The `start` command starts a production-grade Dispatch web server. It's an alias to the [uvicorn](https://www.uvicorn.org/) web server, so it contains all of the options and flags available with that server. @@ -99,7 +99,7 @@ To start Dispatch, you will need to tell the start command where to find the `di > dispatch server start dispatch.main:app --workers 6 --host 127.0.0.1 --port 8000 --proxy-headers ``` -## Scheduler +## Scheduler {#scheduler} The `scheduler` command contains all of the Dispatch scheduler logic. @@ -117,7 +117,7 @@ Commands: start Starts the scheduler. ``` -### List +### List {#list} The `list` command lists all tasks registered with the scheduler. Today the scheduler periods are hardcoded and cannot be adjusted. @@ -145,7 +145,7 @@ case-triage-reminder 1 day, 0:00:00 18:00:00 case-stable-reminder 1 day, 0:00:00 18:00:00 ``` -### Start +### Start {#start-1} The `start` command starts the scheduler and allows tasks to be executed based on the defined period. @@ -160,7 +160,7 @@ Often it's helpful to run a particular task immediately: > dispatch scheduler start incident-status-report-reminder --eager ``` -## Database +## Database {#database} The `database` command contains all of the Dispatch database logic. @@ -191,7 +191,7 @@ Commands: Note: The database command is a combination of custom commands and `alembic` commands. For more information about alembic database migrations, see [here](https://alembic.sqlalchemy.org/en/latest/). ::: -### Init +### Init {#init} The `init` command takes a fresh database and creates the necessary tables and values for Dispatch to operate. @@ -199,7 +199,7 @@ The `init` command takes a fresh database and creates the necessary tables and v > dispatch database init ``` -### Revision +### Revision {#revision} The `revision` command is an `alembic` command that creates a new database schema revision based on the application's models. @@ -209,7 +209,7 @@ Commonly used in conjunction with the `--autogenerate` flag: > dispatch database revision --autogenerate ``` -### Upgrade/Downgrade +### Upgrade/Downgrade {#upgradedowngrade} The `upgrade` and `downgrade` commands manage how `alembic` database migrations are deployed, allowing you to move the database forward and backward through revisions. You'll often need to run the `upgrade` command after installing a new version of Dispatch. @@ -217,17 +217,17 @@ The `upgrade` and `downgrade` commands manage how `alembic` database migrations > dispatch database upgrade ``` -### Restore/Dump +### Restore/Dump {#restoredump} The `restore` and `dump` commands allow you to quickly backup and restore the Dispatch database. It can also be used to load our [example](https://github.com/helldweller/dispatch/blob/main/data/dispatch-sample-data.dump) data set into your Dispatch installation. Today, the `.dump` file must be located in `$CWD` and must be named `dispatch-backup.dump`. -## Plugins +## Plugins {#plugins} The `plugin` command contains all of the logic for dealing with Dispatch's plugins. -### List +### List {#list-1} The `list` command lists all currently available plugins. This command is useful in determining which plugins are available to be used via configuration variables. @@ -242,7 +242,7 @@ Google Group - Participant Group google-group-participant-group 0.1.0 pa ... ``` -### Install +### Install {#install} The `install` command will try installing all available plugins. diff --git a/docs/docs/administration/contributing/plugins/_category_.json b/docs/docs/administration/contributing/plugins/_category_.json new file mode 100644 index 000000000000..c28ff884a889 --- /dev/null +++ b/docs/docs/administration/contributing/plugins/_category_.json @@ -0,0 +1 @@ +{ "label": "Plugins", "key": "contributing-plugins" } diff --git a/docs/docs/administration/faq.mdx b/docs/docs/administration/faq.mdx index 6eba25fe11fd..7a53a5c7119b 100644 --- a/docs/docs/administration/faq.mdx +++ b/docs/docs/administration/faq.mdx @@ -1,6 +1,6 @@ # FAQ -## Running ‘dispatch database upgrade’ seems stuck. +## Running ‘dispatch database upgrade’ seems stuck. {#running-dispatch-database-upgrade-seems-stuck} The upgrade is most likely stuck because an existing query on the database is holding onto a lock that the migration needs. diff --git a/docs/docs/administration/installation.mdx b/docs/docs/administration/installation.mdx index 9c8d2cbac80d..36d389af719b 100644 --- a/docs/docs/administration/installation.mdx +++ b/docs/docs/administration/installation.mdx @@ -8,7 +8,7 @@ tags: Dispatch relies on multiple services to work, which are all orchestrated by `Docker Compose`. -### Requirements +### Requirements {#requirements} - [Docker](https://www.docker.com/) 17.05.0+ - [Docker Compose](https://docs.docker.com/compose/) 1.19.0+ @@ -16,7 +16,7 @@ Dispatch relies on multiple services to work, which are all orchestrated by `Doc - At least 2400MB memory - 2 CPU Cores -## Installing Dispatch Server +## Installing Dispatch Server {#installing-dispatch-server} We strongly recommend using Docker for installing Dispatch and all its services. If you need to do something custom, you can use this repository as the basis of your setup. If you do not wish to use the Docker images we provide, you can still find Dispatch on PyPI; however, we don't recommend that method. You'll need to work your way back from the main Dispatch image. It is not too hard, but you are likely to spend a lot more time and hit some bumps. @@ -46,7 +46,7 @@ To start, run the install script: Note: The `core` Docker service is not needed once the `web` and `schedule` services, which depend on it, are built. ::: -### The "first" user problem +### The "first" user problem {#the-first-user-problem} For any new Dispatch installation, new users are expected to register themselves via the `/auth/register` endpoint in the Dispatch UI. By default, users registering via this method are granted regular "user" permissions within Dispatch. There is no direct way through the UI to allow a user to obtain an "Owner" role (as no other Owners exist to grant them access). @@ -61,11 +61,11 @@ The default organization name in the sample data file is "default". After one owner user has been established, they can grant this role to others via the UI. -## Going to Production +## Going to Production {#going-to-production} Before you deploy Dispatch to production, there are a few considerations and steps that should be taken. -### Basics +### Basics {#basics} Because of the sensitivity of the information stored and maintained by Dispatch. You must follow standard host hardening practices: @@ -74,21 +74,21 @@ Because of the sensitivity of the information stored and maintained by Dispatch. - Enable remote logging - Restrict access to the host -### Credential Management +### Credential Management {#credential-management} Dispatch plugins require API tokens to communicate with third-party resources. These tokens are stored in either an environment variable or in the Dispatch `.env` file. By default, these strings are in plain text, but Dispatch does provide hooks that allow for these credentials to be decrypted on server start. See the [Secret Provider](./settings/server.mdx#general) configuration option. -### Authentication +### Authentication {#authentication} Dispatch provides a "Basic" authentication provider that controls access via a username and password combination to get going quickly. By default, this provider allows for **open registration**, which means that anyone will be able to create a Dispatch account if they have network access to your server. Dispatch provides a "PKCE" authentication method to integrate existing and more robust SSO solutions for more robust authentication. See the [Authentication Provider](./settings/server.mdx#authentication) -### TLS/SSL +### TLS/SSL {#tlsssl} -#### Nginx +#### Nginx {#nginx} Nginx is a popular choice to serve a Python project: diff --git a/docs/docs/administration/settings/authentication-entra-id.mdx b/docs/docs/administration/settings/authentication-entra-id.mdx index e89bfdb88dba..e15cc66a952d 100644 --- a/docs/docs/administration/settings/authentication-entra-id.mdx +++ b/docs/docs/administration/settings/authentication-entra-id.mdx @@ -24,7 +24,7 @@ no allow list. The tenant boundary *is* the authorization boundary, which is why See [Who can sign in](#who-can-sign-in). ::: -## Create the app registration +## Create the app registration {#create-the-app-registration} In the [Microsoft Entra admin center](https://entra.microsoft.com), go to **Identity → Applications → App registrations → New registration**. @@ -38,7 +38,7 @@ In the [Microsoft Entra admin center](https://entra.microsoft.com), go to Record the **Application (client) ID** and the **Directory (tenant) ID** from the registration's Overview page. -### Supported account types +### Supported account types {#supported-account-types} Choose **single tenant**. Dispatch has no per-user approval step, so a multitenant registration means any Microsoft work, school, or personal account in the world @@ -46,7 +46,7 @@ can sign in and be provisioned. Only pick multitenant if you genuinely intend to admit guests from other directories, and pair it with a separate authorization control — the issuer setting below can only pin one tenant. -### Redirect URI +### Redirect URI {#redirect-uri} The redirect URI must be registered under the **Single-page application** platform, not **Web**. That is what makes Entra: @@ -64,7 +64,7 @@ this one URI needs registering however many routes the app has. Add `http://localhost:8080/implicit/callback` as a second URI if you want the local dev server to sign in against the same registration. -### Client secret +### Client secret {#client-secret} **Do not create one.** A single-page application is a public client; Microsoft documents that SPAs must not use secrets or certificates when redeeming an @@ -72,7 +72,7 @@ authorization code, and Entra refuses client credentials on any request carrying an `Origin` header. Dispatch never sends one and has nowhere to put one that the browser could not read. PKCE, not a secret, is what binds the code to this client. -### Scopes and permissions +### Scopes and permissions {#scopes-and-permissions} `openid`, `profile` and `email` — the three OpenID Connect scopes the frontend already requests. Nothing else. These are delegated permissions that need no @@ -82,7 +82,7 @@ the user's identity out of the ID token and never calls Graph. Leave **API permissions** at the `User.Read` default Entra adds, or remove it. Dispatch does not use it. -### Token claims +### Token claims {#token-claims} Dispatch needs exactly one claim: an email address to key the user on. By default it reads `email`, but Entra emits `email` for a managed user only if you add it as @@ -101,7 +101,7 @@ addresses — Dispatch also uses this value to match people to incidents and to address notifications — add `email` under **Token configuration → Add optional claim → ID → email** and leave `DISPATCH_JWT_EMAIL_OVERRIDE` unset instead. -## Configure Dispatch +## Configure Dispatch {#configure-dispatch} With `` and `` from the registration: @@ -136,7 +136,7 @@ Notes on the less obvious ones: * Settings prefixed `VITE_` are read when the frontend bundle is **built**, not when the server starts — see [Frontend build](#frontend-build). -### Restricting sign-in to your tenant +### Restricting sign-in to your tenant {#restricting-sign-in-to-your-tenant} Two things do this, and both matter: @@ -155,7 +155,7 @@ with Dispatch's: set **Enterprise applications → Dispatch → Properties → Assignment required** to **Yes** and assign the groups that should have access. Dispatch has no equivalent. -### Frontend build +### Frontend build {#frontend-build} The three `VITE_`-prefixed values are compiled into the JavaScript bundle, so changing them means rebuilding the frontend, not restarting the server. When @@ -174,7 +174,7 @@ The backend settings are ordinary environment variables and take effect on restart. None of them is a secret, so they are safe in a Compose file or an image build log — there is no client secret anywhere in this configuration. -## Who can sign in +## Who can sign in {#who-can-sign-in} Dispatch provisions on first sight. The first request carrying an ID token it accepts creates a `DispatchUser` with the `Member` role in the organization being @@ -189,7 +189,7 @@ Consequently: **Settings → Users**, or with `dispatch user update --role owner --organization `. -### Existing Dispatch users +### Existing Dispatch users {#existing-dispatch-users} Users are keyed by email address, and that does not change when you enable Entra. An account that already exists — created by basic auth self-registration, by an @@ -212,14 +212,14 @@ resolved back to an address anyway. The tenant restriction, not the claim's immutability, is what makes the address trustworthy. ::: -## Verifying it works +## Verifying it works {#verifying-it-works} 1. Restart the server (and rebuild the frontend) with the settings above. 2. Open Dispatch. You should be redirected to `login.microsoftonline.com` and back. 3. Check the server log at startup. The PKCE provider warns about anything it needs and does not have — a missing JWKS URL, issuer, or audience. -### Troubleshooting +### Troubleshooting {#troubleshooting} | Symptom | Cause | | --- | --- | @@ -231,7 +231,7 @@ immutability, is what makes the address trustworthy. | 401 with *Token carries no 'email' claim* | Set `DISPATCH_JWT_EMAIL_OVERRIDE=preferred_username`, or add the `email` optional claim. | | `AADSTS50011`, redirect URI mismatch | The registered URI must be the deployment origin plus `/implicit/callback`, exactly. | -## Reverting to another provider +## Reverting to another provider {#reverting-to-another-provider} There is nothing to undo in the database — Entra sign-in creates ordinary Dispatch users. To go back to basic authentication, set diff --git a/docs/docs/administration/settings/contact/individual.mdx b/docs/docs/administration/settings/contact/individual.mdx index c1f6ee578aa7..6a4d97685b3f 100644 --- a/docs/docs/administration/settings/contact/individual.mdx +++ b/docs/docs/administration/settings/contact/individual.mdx @@ -16,6 +16,6 @@ It's common for incident response teams to maintain a list of contacts and run b **Company:** Company associated with the individual. -#### Engagement +#### Engagement {#engagement} In addition to fields about the individual, Dispatch allows you to associate the individual with other Dispatch primitives. For instance, if you would like to involve an individual for all incidents of a given priority, associate that priority with the individual. diff --git a/docs/docs/administration/settings/contact/service.mdx b/docs/docs/administration/settings/contact/service.mdx index 0da8dffb2007..39c80f304a38 100644 --- a/docs/docs/administration/settings/contact/service.mdx +++ b/docs/docs/administration/settings/contact/service.mdx @@ -18,6 +18,6 @@ Like `Teams`, there are often groups of individuals (teams) responsible for an a **Enabled:** Flag that determines if this particular service is active. -#### Engagement +#### Engagement {#engagement} In addition to the service fields, Dispatch allows you to associate the service with other Dispatch primitives. For instance, if you would like to involve a service for all incidents of a given priority, associate that priority with the service. diff --git a/docs/docs/administration/settings/contact/team.mdx b/docs/docs/administration/settings/contact/team.mdx index 9623ae090afc..361585be3845 100644 --- a/docs/docs/administration/settings/contact/team.mdx +++ b/docs/docs/administration/settings/contact/team.mdx @@ -14,6 +14,6 @@ Like `Individuals`, there are often groups of individuals (teams) that need to b **Company:** Company associated with the team. -#### Engagement +#### Engagement {#engagement} In addition to fields about the team, Dispatch allows you to associate a team with other Dispatch primitives. For instance, if you would like to involve an entire team for all incidents of a given priority, associate that priority with the team. diff --git a/docs/docs/administration/settings/cost_model.mdx b/docs/docs/administration/settings/cost_model.mdx index 35be4369f1fa..f8a4c985e892 100644 --- a/docs/docs/administration/settings/cost_model.mdx +++ b/docs/docs/administration/settings/cost_model.mdx @@ -10,27 +10,27 @@ If an incident type does not have a specific cost model assigned, the default cl -## Key Features +## Key Features {#key-features} -### Customizable Cost Models +### Customizable Cost Models {#customizable-cost-models} Users have the flexibility to define their unique cost models based on their organization's workflow and tools. This customization can be tailored to each incident type, providing a versatile approach to cost calculation. The cost model for an incident type can be changed at any time. When cost model changes are made to the incident type or an incident changes its type, all participant activity costs moving forward will be calculated using the new cost model. -### Plugin-Based Tracking +### Plugin-Based Tracking {#plugin-based-tracking} Users can track costs from their existing tools by using our plugin-based tracking system. Users have the flexibility to select which plugins and specific plugin events they want to track, offering a targeted approach to cost calculation. -### Effort Assignment +### Effort Assignment {#effort-assignment} For each tracked activity, users can assign a quantifiable measure of effort, represented in seconds of work time. This feature provides a more accurate representation of the cost of an incident. -### Incident Cost Calculation +### Incident Cost Calculation {#incident-cost-calculation} Incident cost calculation is based on the cost model and effort assignment for each tracked participant activity. This helps in understanding resource utilization and cost of an incident. -## Currently Supported Plugin Events +## Currently Supported Plugin Events {#currently-supported-plugin-events} -### Slack: Channel Activity +### Slack: Channel Activity {#slack-channel-activity} This event tracks activity within a specific Slack channel. By periodically polling channel messages, this gathers insights into the activity and engagement levels of each participant. -### Slack: Thread Activity +### Slack: Thread Activity {#slack-thread-activity} This event tracks activity within a specific Slack thread. By periodically polling thread replies, this gathers insights into the activity and engagement levels of each participant. @@ -40,7 +40,7 @@ This event tracks activity within a specific Slack thread. By periodically polli -## Cost Calculation Examples +## Cost Calculation Examples {#cost-calculation-examples} Below, we illustrate the use of the cost model through two examples. These are based on the following values: @@ -55,7 +55,7 @@ The employee hourly rate can be adjusted by modifying the `Annual Employee Cost` hourly_rate = 100 ``` -#### Example 1 +#### Example 1 {#example-1} Consider the following Slack channel activity for `Incident 1`: @@ -78,7 +78,7 @@ The incident cost is then calculated as: ( (400 - 100) + (500 - 200) ) / SECONDS_IN_HOUR * hourly_rate = $16.67 ``` -#### Example 2 +#### Example 2 {#example-2} Consider the following Slack channel activity for `Incident 2`: diff --git a/docs/docs/administration/settings/incident/incident-cost-type.mdx b/docs/docs/administration/settings/incident/incident-cost-type.mdx index e873721c630f..9fff1b2f0cbe 100644 --- a/docs/docs/administration/settings/incident/incident-cost-type.mdx +++ b/docs/docs/administration/settings/incident/incident-cost-type.mdx @@ -18,7 +18,7 @@ Dispatch allows you to define incident cost types. These types can then be used **Editable:** Whether this cost type can be edited or not. -### Calculating Incident Cost +### Calculating Incident Cost {#calculating-incident-cost} Dispatch [calculates](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L279) the cost of an incident by adding up the time participants have spent on each incident role \(e.g., Incident Commander\) and applying an [engagement multiplier](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L266) that's based on the incident role. It also includes time spent on incident review-related activities. Dispatch calculates and publishes the cost for all incidents [every 5 minutes](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/scheduled.py#L257). diff --git a/docs/docs/administration/settings/knowledge/runbooks.mdx b/docs/docs/administration/settings/knowledge/runbooks.mdx index 0cae1acfaa6a..7a34b47a89ed 100644 --- a/docs/docs/administration/settings/knowledge/runbooks.mdx +++ b/docs/docs/administration/settings/knowledge/runbooks.mdx @@ -11,7 +11,7 @@ Today, there are two types of runbooks although their actual usage is the same. - Incident - Investigation -### Engagement +### Engagement {#engagement} Runbook documents are dynamically matched to an incident based on their engagement filter. Similar to notification's a user can define for which incidents a document should be recommended to incident participants. @@ -31,6 +31,6 @@ On incident creation (or when an important incident variable changes e.g. incide **ID:** The external ID that is used to fetch the document. -### Evergreen +### Evergreen {#evergreen} Enabling evergreen for a runbook instructs Dispatch to send an email reminder to the runbook owner, informing them that they should check to ensure that the runbook in question is up to date. diff --git a/docs/docs/administration/settings/messaging.mdx b/docs/docs/administration/settings/messaging.mdx index 607397ae295d..bba45ca6f6e5 100644 --- a/docs/docs/administration/settings/messaging.mdx +++ b/docs/docs/administration/settings/messaging.mdx @@ -2,7 +2,7 @@ Dispatch supports sending email notifications to participants of, for example, an incident. -## Notification templates +## Notification templates {#notification-templates} Templates for emails are [part](https://github.com/helldweller/dispatch/tree/main/src/dispatch/messaging/email/templates) of Dispatch and are [Jinja](https://jinja.palletsprojects.com/) templates that during runtime are compiled into [MJML](https://mjml.io/) format. @@ -33,7 +33,7 @@ otherwise the resolution process will gracefully fall back to the default templa dispatch/messaging/email/templates/base.mjml ``` -## Markdown in the notifications +## Markdown in the notifications {#markdown-in-the-notifications} :::warning Watch out for security implications related to unescaped HTML that may propagate through the system. diff --git a/docs/docs/administration/settings/plugins/_category_.json b/docs/docs/administration/settings/plugins/_category_.json new file mode 100644 index 000000000000..927d13274f86 --- /dev/null +++ b/docs/docs/administration/settings/plugins/_category_.json @@ -0,0 +1 @@ +{ "label": "Plugins", "key": "settings-plugins" } diff --git a/docs/docs/administration/settings/plugins/configuring-atlassian-confluence.mdx b/docs/docs/administration/settings/plugins/configuring-atlassian-confluence.mdx index c96ef7922aa4..92add3d57e84 100644 --- a/docs/docs/administration/settings/plugins/configuring-atlassian-confluence.mdx +++ b/docs/docs/administration/settings/plugins/configuring-atlassian-confluence.mdx @@ -8,25 +8,25 @@ description: Configuration page for Atlassian Confluence. Dispatch ships with Atlassian Confluence storage and document plugins. This page describes the available configurations for the plugins. ::: -## Dispatch configuration variables for storage plugin +## Dispatch configuration variables for storage plugin {#dispatch-configuration-variables-for-storage-plugin} -### `API URL` \[Required\] +### `API URL` \[Required\] {#api-url-required} > URL of the Confluence instance. For Cloud this is the site root, for example `https://your-site.atlassian.net/`; Dispatch appends the `/wiki` path itself, including for a site on a custom domain. For Server/Data Center this is the instance URL, including any context path it is served under. -### `Hosting Type` \[Default: cloud\] +### `Hosting Type` \[Default: cloud\] {#hosting-type-default-cloud} > Either `cloud` or `server`. Dispatch reaches Confluence Cloud over the REST v2 API and Confluence Server/Data Center over REST v1; these are different APIs, so this must match the deployment. -### `Username` \[Required\] +### `Username` \[Required\] {#username-required} > Username for accessing the confluence instance. This user should have permission to create pages in the space. -### `Password` \[Required\] +### `Password` \[Required\] {#password-required} > API token to access the confluence instance. Please refer to the [link](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/) on creating a new API token. -### `Root Incident Storage Page ID` \[Required\] +### `Root Incident Storage Page ID` \[Required\] {#root-incident-storage-page-id-required} > Page id of the page each incident's own page is created under, found in the page URL: `/pages//`. > @@ -38,7 +38,7 @@ Dispatch ships with Atlassian Confluence storage and document plugins. This page > Earlier releases took a space key here, alongside a separate `Parent ID of the pages` field. Upgrading moves that parent page id into this field and drops the old one, so an existing instance needs no edit. Setting it by hand is the case to watch: a space key cannot be read as a page, so no incident storage is created and each attempt logs `Exception happened while creating page … under <space key>`. > ::: -### `Open On Close` \[Default: false\] +### `Open On Close` \[Default: false\] {#open-on-close-default-false} > Controls the visibility of resources on incident close. If enabled, Dispatch will make all resources visible to the entire workspace. > @@ -46,7 +46,7 @@ Dispatch ships with Atlassian Confluence storage and document plugins. This page > The Confluence plugin does not implement this yet; the setting is accepted and has no effect. Closing an incident logs a failure event for the attempt. > ::: -### `Readonly` \[Default: false\] +### `Readonly` \[Default: false\] {#readonly-default-false} > The incident document will be marked as readonly on incident close. Participants will still be able to interact with the document but any other viewers will not. > @@ -54,20 +54,20 @@ Dispatch ships with Atlassian Confluence storage and document plugins. This page > The Confluence plugin does not implement this yet, in the same way as `Open On Close` above. > ::: -## Dispatch Configuration Variables for document plugin +## Dispatch Configuration Variables for document plugin {#dispatch-configuration-variables-for-document-plugin} -### `API URL` \[Required\] +### `API URL` \[Required\] {#api-url-required-1} > URL of the Confluence instance. For Cloud this is the site root, for example `https://your-site.atlassian.net/`; Dispatch appends the `/wiki` path itself, including for a site on a custom domain. For Server/Data Center this is the instance URL, including any context path it is served under. -### `Hosting Type` \[Default: cloud\] +### `Hosting Type` \[Default: cloud\] {#hosting-type-default-cloud-1} > Either `cloud` or `server`. Dispatch reaches Confluence Cloud over the REST v2 API and Confluence Server/Data Center over REST v1; these are different APIs, so this must match the deployment. -### `Username` \[Required\] +### `Username` \[Required\] {#username-required-1} > Username for accessing the confluence instance. This user should have permission to create pages in the space. -### `Password` \[Required\] +### `Password` \[Required\] {#password-required-1} > API token to access the confluence instance. Please refer to the [link](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/) on creating a new API token. diff --git a/docs/docs/administration/settings/plugins/configuring-duo.mdx b/docs/docs/administration/settings/plugins/configuring-duo.mdx index 58b5749c044b..ddde6a5671fe 100644 --- a/docs/docs/administration/settings/plugins/configuring-duo.mdx +++ b/docs/docs/administration/settings/plugins/configuring-duo.mdx @@ -8,18 +8,18 @@ description: Configuration options for the Duo plugin. Dispatch ships with Duo support for additional multi-factor authentication checks within the application, such as when a snooze rule is created. This plugin is not required for core functionality. ::: -## `Integration Key` \[Required. Secret: True\] +## `Integration Key` \[Required. Secret: True\] {#integration-key-required-secret-true} > Auth API integration key ('DI...'). -## `Integration Secret Key` \[Required. Secret: True\] +## `Integration Secret Key` \[Required. Secret: True\] {#integration-secret-key-required-secret-true} > Secret token used in conjunction with integration key. -## `API Hostname` \[Required\] +## `API Hostname` \[Required\] {#api-hostname-required} > API hostname ('api-....duosecurity.com') -## Duo Setup +## Duo Setup {#duo-setup} Log in to the Duo Admin Panel and navigate to `Applications`. Click `Protect an Application` and locate the entry for Auth API in the applications list. Click `Protect` to the far-right to configure the application and get your `integration key`, `secret key`, and `API hostname`. diff --git a/docs/docs/administration/settings/plugins/configuring-g-suite.mdx b/docs/docs/administration/settings/plugins/configuring-g-suite.mdx index 251b07ff9f74..7dffdf88b7d8 100644 --- a/docs/docs/administration/settings/plugins/configuring-g-suite.mdx +++ b/docs/docs/administration/settings/plugins/configuring-g-suite.mdx @@ -9,53 +9,53 @@ Dispatch ships with several G Suite plugins \(Docs, Groups, Drive, etc.,\). This for these plugins and the permissions required to enable them. ::: -## Dispatch Configuration +## Dispatch Configuration {#dispatch-configuration} The G Suite plugins are configured in the Dispatch Web UI under Settings -> Project -> Plugins. Add the desired plugin(s) using the `NEW` button and then edit their configuration by clicking on the three vertical dots. -### Developer Key +### Developer Key {#developer-key} > This is used by the Google API Discovery Service and prevents rate limiting. -### Service Account Client Email +### Service Account Client Email {#service-account-client-email} > The `client_email` value from your Google Cloud Platform \(GCP\) service account configuration file. -### Service Account Client Id +### Service Account Client Id {#service-account-client-id} > The `client_id` value from your Google Cloud Platform \(GCP\) service account configuration file. -### Service Account Delegated Account +### Service Account Delegated Account {#service-account-delegated-account} > Account to delegate to from the Google Cloud Platform \(GCP\) service account. > Outgoing emails and other artifacts will appear to be from this account. -### Service Account Private Key +### Service Account Private Key {#service-account-private-key} > The `private_key` value from your Google Cloud Platform \(GCP\) service account configuration file. -### Service Account Private Key Id +### Service Account Private Key Id {#service-account-private-key-id} > The `private_key_id` value from your Google Cloud Platform \(GCP\) service account configuration file. -### Service Account Project Id +### Service Account Project Id {#service-account-project-id} > The `project_id` value from your Google Cloud Platform \(GCP\) service account configuration file. -### Google Workspace Domain +### Google Workspace Domain {#google-workspace-domain} > Base domain for which this Google Cloud Platform \(GCP\) service account resides. -### Default Event Duration (Minutes) +### Default Event Duration (Minutes) {#default-event-duration-minutes} > Default duration in minutes for conference events. Defaults to 1440 minutes (1 day). -## G Suite Setup +## G Suite Setup {#g-suite-setup} To set up G Suite integration, you'll need to create some resources in Google Cloud Platform and then link them to your G Suite organization. -## Enable Required APIs in Google Cloud Platform +## Enable Required APIs in Google Cloud Platform {#enable-required-apis-in-google-cloud-platform} Navigate to the Google Cloud Platform \(GCP\) [console](https://console.cloud.google.com/). You will want to create a new GCP Project for Dispatch's integration. @@ -99,7 +99,7 @@ https://www.googleapis.com/auth/calendar **Note:** If you will not use Google Meet for your conference, then you do not need the `https://www.googleapis.com/auth/calendar` scope. -## Connecting Dispatch to G Suite +## Connecting Dispatch to G Suite {#connecting-dispatch-to-g-suite} Navigate to the G Suite Admin [Domain-wide Delegation](https://admin.google.com/ac/owl/domainwidedelegation) page \(Security > API Controls > Domain-wide Delegation\) and add a new API client. diff --git a/docs/docs/administration/settings/plugins/configuring-jira.mdx b/docs/docs/administration/settings/plugins/configuring-jira.mdx index b1320118e09f..86aab75dee8a 100644 --- a/docs/docs/administration/settings/plugins/configuring-jira.mdx +++ b/docs/docs/administration/settings/plugins/configuring-jira.mdx @@ -8,34 +8,34 @@ description: Configuration options for the Jira plugin. Dispatch ships with Jira support. Each Jira installation is unique, so you will likely want to create a Jira-specific plugin for your organization. This plugin is not required for core functionality. However, a plugin of type `ticket` must always be enabled. ::: -## Dispatch Configuration +## Dispatch Configuration {#dispatch-configuration} The Jira plugin is configured in the Dispatch Web UI under Settings -> Project -> Plugins. Add the plugin using the `NEW` button and then edit its configuration by clicking on the three vertical dots. -### Default Project Id or Key +### Default Project Id or Key {#default-project-id-or-key} > Defines the default Jira Project to use. You can find the Jira project id like [this](https://community.atlassian.com/t5/Jira-questions/JIRA-Project-ID/qaq-p/193094) or like [this](https://confluence.atlassian.com/jirakb/how-to-get-project-id-from-the-jira-user-interface-827341414.html). -### Default Issue Type Name +### Default Issue Type Name {#default-issue-type-name} > Defines the default Jira issue type name to use. -### Hosting Type +### Hosting Type {#hosting-type} > Defines the type of deployment (`cloud` or `server`). Defaults to `cloud`. -### Username +### Username {#username} > Username to use to authenticate to the Jira API. -### Password +### Password {#password} > Password to use to authenticate to the Jira API. -### API URL +### API URL {#api-url} > This URL is used for communication with the Jira API. -### Browser URL +### Browser URL {#browser-url} > This URL is used to construct browser weblinks. diff --git a/docs/docs/administration/settings/plugins/configuring-microsoft-teams.mdx b/docs/docs/administration/settings/plugins/configuring-microsoft-teams.mdx index dd2e9c434390..9e6523bef481 100644 --- a/docs/docs/administration/settings/plugins/configuring-microsoft-teams.mdx +++ b/docs/docs/administration/settings/plugins/configuring-microsoft-teams.mdx @@ -8,15 +8,15 @@ description: Configuration options for the Microsoft Teams conference plugin. The Microsoft Teams plugin creates a Teams online meeting to act as the incident bridge. It authenticates to Microsoft Graph with the OAuth2 client-credentials flow and creates the meeting on behalf of a nominated user. Teams meetings expire 60 days after the meeting's start or end time (extended by another 60 days if the meeting is updated or activated), so the join link stays usable for the life of an incident regardless of the configured duration. ::: -## Azure Setup +## Azure Setup {#azure-setup} The plugin acts as an application, not as a signed-in user, so it needs an app registration with an **application** permission and a Teams policy that names the user it creates meetings for. Both halves are required — a valid token without the policy returns `403`. -### 1. Register an application +### 1. Register an application {#1-register-an-application} In the [Microsoft Entra admin center](https://entra.microsoft.com), go to **App registrations → New registration**. Note the **Application (client) ID** and the **Directory (tenant) ID**. -### 2. Grant the Graph permission +### 2. Grant the Graph permission {#2-grant-the-graph-permission} Under **API permissions**, add **Microsoft Graph → Application permissions → `OnlineMeetings.ReadWrite.All`**, then **Grant admin consent**. @@ -24,11 +24,11 @@ Under **API permissions**, add **Microsoft Graph → Application permissions → It must be an *application* permission. Delegated permissions apply to a signed-in user and are not used by this plugin. ::: -### 3. Create a client secret +### 3. Create a client secret {#3-create-a-client-secret} Under **Certificates & secrets → New client secret**, copy the secret **value** (not the ID). It is only shown once. Client secrets expire — set a reminder, because an expired secret surfaces as `invalid_client` in the incident timeline. -### 4. Allow the application to create meetings for a user +### 4. Allow the application to create meetings for a user {#4-allow-the-application-to-create-meetings-for-a-user} This is the step that is easy to miss. Grant the application access to the user whose calendar the meetings are created under: @@ -45,35 +45,35 @@ Grant-CsApplicationAccessPolicy -PolicyName Dispatch-Conference ` Policy assignment can take up to 30 minutes to take effect. See [Allow applications to access online meetings on behalf of a user](https://learn.microsoft.com/en-us/graph/cloud-communication-online-meeting-application-access-policy). -## Dispatch Configuration +## Dispatch Configuration {#dispatch-configuration} The Microsoft Teams plugin is configured in the Dispatch Web UI under Settings -> Project -> Plugins. Add the plugin using the `NEW` button and then edit its configuration by clicking on the three vertical dots. -### MS team Authority URL +### MS team Authority URL {#ms-team-authority-url} > `https://login.microsoftonline.com/<directory-tenant-id>`. Use a specific tenant; `common` and `organizations` are not supported for the client-credentials flow. -### client id +### client id {#client-id} > The Application (client) ID from step 1. -### Azure Client Secret +### Azure Client Secret {#azure-client-secret} > The client secret value from step 3. -### User id +### User id {#user-id} > The **object ID** of the user the application creates meetings on behalf of — not their email address. This must be the same user named in the application access policy in step 4. -### Allow Auto Recording +### Allow Auto Recording {#allow-auto-recording} > Enable if you would like to record the meetings by default. Defaults to disabled. -### Default Meeting Duration (Minutes) +### Default Meeting Duration (Minutes) {#default-meeting-duration-minutes} > Default duration in minutes for conference meetings. Defaults to 1440 minutes (1 day). Teams meetings stay joinable past their scheduled end, so this mainly sets when the meeting expires rather than cutting the bridge off. -### Require a Meeting Passcode +### Require a Meeting Passcode {#require-a-meeting-passcode} > Require a passcode when joining by meeting ID. Defaults to enabled. > @@ -81,7 +81,7 @@ The Microsoft Teams plugin is configured in the Dispatch Web UI under Settings - > > Because the passcode is useless without the meeting ID it pairs with, Dispatch publishes both together: the conference description reads `Password: aB3dEf7h (meeting ID 123 456 789)`. -## Troubleshooting +## Troubleshooting {#troubleshooting} Failures are recorded on the incident timeline with the reason Graph gave. @@ -92,11 +92,11 @@ Failures are recorded on the incident timeline with the reason Graph gave. | `404` on create | The **User id** is not an object ID, or the user does not exist in the tenant. | | `429` | Graph is throttling the application. The message carries the `Retry-After` value verbatim (Graph sends either a seconds count or an HTTP date). Dispatch does not retry — a retry on a write endpoint risks creating a second bridge for one incident. | -## Limits +## Limits {#limits} Microsoft documents a limit of **2,000 meetings per user per month** for meeting information. Because Dispatch creates every bridge under the single user configured above, that is the ceiling this plugin will reach first. Microsoft does not publish a per-second rate for `/onlineMeetings` in its service-specific throttling table; if the application is throttled, Graph answers `429` with `Retry-After` and Dispatch surfaces both on the incident timeline. -## Notes +## Notes {#notes} - `add_participant` and `remove_participant` keep the meeting's attendee list in step with the incident's participants. This is **roster metadata, not access control**: the join link works for anyone who holds it, so being added grants nothing that the published link does not already grant, and being removed neither evicts a participant from a meeting in progress nor invalidates the link. Attendees are added with the `attendee` role — Microsoft does not support assigning `presenter` or `coorganizer` to identities Entra cannot resolve, and responders may be external. - Graph replaces the whole attendee list on every update, so Dispatch reads the meeting before each change and resends the existing attendees unchanged. A failure is recorded on the incident timeline and does not interrupt adding or removing the participant everywhere else. @@ -106,7 +106,7 @@ Microsoft documents a limit of **2,000 meetings per user per month** for meeting - The meeting is created with an initial attendee roster: the responders resolved for the incident, minus anyone who has turned off **Add me automatically to incident bridges** in their own settings. Same list, same `attendee` role and same caveats as `add_participant` above — it is created in one request rather than added afterwards, so a roster Graph rejects fails the create instead of leaving a meeting Dispatch has no record of. An incident with no such responders gets a meeting with no attendees, which is not an error. - `description` is accepted by the plugin and unused: an `onlineMeeting` has no agenda field. -## Upgrading +## Upgrading {#upgrading} Before the fixes in [Jamyn/dispatch#81](https://github.com/Jamyn/dispatch/issues/81) this plugin could not authenticate at all — it passed a string where MSAL requires a list of scopes, so every attempt raised before reaching Graph and was swallowed. Any existing deployment was therefore producing no bridges, and there is no prior working behaviour to preserve. Two things nonetheless differ from what the old code *attempted*: diff --git a/docs/docs/administration/settings/plugins/configuring-opsgenie.mdx b/docs/docs/administration/settings/plugins/configuring-opsgenie.mdx index 831251cc452c..c355d86b24a2 100644 --- a/docs/docs/administration/settings/plugins/configuring-opsgenie.mdx +++ b/docs/docs/administration/settings/plugins/configuring-opsgenie.mdx @@ -8,10 +8,10 @@ description: Configuration options for the Opsgenie plugin. Dispatch ships with support for resolving on-call schedules via the Opsgenie API. Below is how to configure the Opsgenie plugin to work with `Dispatch.` ::: -## Dispatch Configuration +## Dispatch Configuration {#dispatch-configuration} The Opsgenie plugin is configured in the Dispatch Web UI under Settings -> Project -> Plugins. Add the plugin using the `NEW` button and then edit its configuration by clicking on the three vertical dots. -### API Key +### API Key {#api-key} > This is the key used to talk to the Opsgenie API. diff --git a/docs/docs/administration/settings/plugins/configuring-pagerduty.mdx b/docs/docs/administration/settings/plugins/configuring-pagerduty.mdx index cd04d1d46d5b..669bab3e9d42 100644 --- a/docs/docs/administration/settings/plugins/configuring-pagerduty.mdx +++ b/docs/docs/administration/settings/plugins/configuring-pagerduty.mdx @@ -8,23 +8,23 @@ description: Configuration options for the PagerDuty plugin. Dispatch ships with support for resolving on-call schedules via the PagerDuty API. ::: -### Dispatch Configuration +### Dispatch Configuration {#dispatch-configuration} The PagerDuty plugin is configured in the Dispatch Web UI under Settings -> Project -> Plugins. Add the plugin using the `NEW` button and then edit its configuration by clicking on the three vertical dots. -#### API Key +#### API Key {#api-key} > This is the key used to talk to the PagerDuty API. See: https://support.pagerduty.com/docs/generating-api-keys -#### From Email +#### From Email {#from-email} > This the email to put into the 'From' field of any page requests. -#### Instance API URL +#### Instance API URL {#instance-api-url} > Enter the URL for your API (defaults to `https://api.pagerduty.com`, i.e. the US instance). -## Oncall Service Configuration +## Oncall Service Configuration {#oncall-service-configuration} Go to /services on your Web server running Dispatch and add a new service. Select type `pagerduty-oncall` and add your PagerDuty Service ID in the external id field. diff --git a/docs/docs/administration/settings/plugins/configuring-slack.mdx b/docs/docs/administration/settings/plugins/configuring-slack.mdx index 105991aa8ae5..201649ca5b35 100644 --- a/docs/docs/administration/settings/plugins/configuring-slack.mdx +++ b/docs/docs/administration/settings/plugins/configuring-slack.mdx @@ -6,7 +6,7 @@ description: Configuration options for the Slack plugin. Dispatch ships with support for Slack. Below is how to configure the Slack plugin to work with `Dispatch`. -## Events Mode vs Socket Mode +## Events Mode vs Socket Mode {#events-mode-vs-socket-mode} Dispatch supports both [Events Mode](https://api.slack.com/events-api) and [Socket Mode](https://api.slack.com/apis/connections/socket). @@ -17,7 +17,7 @@ Which mode should you choose? See the [Dispatch Configuration](#dispatch-configuration) section below for further details on the variables. -### Events Mode +### Events Mode {#events-mode} Events mode requires specific URL mapping that must be **publicly** accessible: @@ -25,7 +25,7 @@ Events mode requires specific URL mapping that must be **publicly** accessible: - `Dispatch` receives command events at the `/api/v1/<organization>/events/slack/command` endpoint (`/dispatch-*` commands) - `Dispatch` receives action events at the `/api/v1/<organization>/events/slack/action` endpoint (dialogs and modals). -### Socket Mode +### Socket Mode {#socket-mode} To enable socket mode, add the socket mode app token in the `Socket Mode App Token` section of the `Slack Plugin - Conversation Management` and the `Slack Plugin - Contact Information Resolver` plugins Dispatch Web UI under Settings -> Project -> Plugins. @@ -41,11 +41,11 @@ dispatch server slack <organization> <project> This process has to be daemonized similarly to the Dispatch webserver. -## Slack Configuration +## Slack Configuration {#slack-configuration} You will need to set the following configuration settings for your Slack app in the [Slack API Web UI](https://api.slack.com/apps) for both `events mode` and `socket mode`. -### Event Subscriptions +### Event Subscriptions {#event-subscriptions} To enable Dispatch to process Slack events, under `Events Subscriptions`, ensure that the `Request URL` points to the events subscription API endpoint of the Dispatch server at `/api/v1/<organization>/events/slack/event`. Replace `<organization>` with your organization's name. The default one is `default`. @@ -57,17 +57,17 @@ Then, under the `Subscribe to bot events` section, add the following bot user ev | member_left_channel | A user left a public or private channel | | message.groups | A message was posted to a private channel | -### Interactivity +### Interactivity {#interactivity} To enable Dispatch to generate interactive components such as dialogs and modals, ensure that the `Request URL` points to the events action API endpoint of the Dispatch server at `/api/v1/<organization>/events/slack/action`. Replace `<organization>` with your organization's name. The default one is `default`. -### Select Menus +### Select Menus {#select-menus} On the same `Interactivity & Shortcuts` page, under `Select Menus`, set the `Options Load URL` to `/api/v1/<organization>/events/slack/menu`. Replace `<organization>` with your organization's name. The default one is `default`. This is a separate field from the `Request URL` above and does not inherit from it. Dispatch uses it for the type-ahead menus that load their choices on demand rather than embedding them in the modal: tag selection, and project selection in deployments with more than 100 enabled projects. If it is unset, those menus open empty and stay empty, and because the field is required the form cannot be submitted. -### Slash Commands +### Slash Commands {#slash-commands} To enable Dispatch's slash commands, you must add them to your Slack app first. Ensure that the `Command` field in the Slack API Web UI matches the name of the command name in the Slack plugin in the Dispatch Web UI and that the `Request URL` points to the events command API endpoint of the Dispatch server at `/api/v1/<organization>/events/slack/command`. @@ -89,11 +89,11 @@ To enable Dispatch's slash commands, you must add them to your Slack app first. </div> -### OAuth & Permissions +### OAuth & Permissions {#oauth--permissions} The `Bot User OAuth Access Token` is used to issue queries against the Slack API. -#### Scopes +#### Scopes {#scopes} The following are the bot and user scopes required for the Dispatch Slack App to function correctly. @@ -132,41 +132,41 @@ groups:history groups:read ``` -## Dispatch Configuration +## Dispatch Configuration {#dispatch-configuration} The Dispatch Slack plugins for conversation management and resolving contact information are configured in the Dispatch Web UI under Settings -> Project -> Plugins. Add the desired plugin(s) using the `NEW` button and then edit the plugin(s) configuration by clicking on the three vertical dots. -### Conversation Management Plugin +### Conversation Management Plugin {#conversation-management-plugin} -#### API Bot Token +#### API Bot Token {#api-bot-token} > The Slack app's bot token necessary to communicate with the Slack API. Slack refers to this as your "Bot User OAuth Access Token" and should be revealed to app collaborators when installing the app. -#### Socket Mode App Token +#### Socket Mode App Token {#socket-mode-app-token} > The Slack app's socket mode token provided when socket mode is enabled to authenticate to the WebSocket API. Its value will be ignored if socket mode is not used. -#### Signing Secret +#### Signing Secret {#signing-secret} > The secret used to verify signatures included on each HTTP request that Slack sends. Slack refers to this as your "Signing Secret." -#### App User Id +#### App User Id {#app-user-id} > The Slack app's bot user id so that Dispatch can filter events generated by the app's user \(e.g., message posted in the channel\). You can use the [auth.test](https://api.slack.com/methods/auth.test/test) endpoint and the app's bot token \(`xoxb-*`\) to get the bot user-id \(`UXXXXXXXX`\)." -#### Private Channels +#### Private Channels {#private-channels} > Whether you want Dispatch to create public or private incident Slack channels. -#### Ban Threads +#### Ban Threads {#ban-threads} > Whether you want Dispatch to allow or ban threaded messages in incident channels. -#### Timeline Event Reaction +#### Timeline Event Reaction {#timeline-event-reaction} > The reaction used for adding Slack messages posted in the incident channel to the incident timeline. -#### Command Strings +#### Command Strings {#command-strings} > The name of the slash commands that your Slack app will expose. @@ -203,29 +203,29 @@ You can override their values if you wish to do so. Included below are their des | `/dispatch-engage-user` | Opens a modal to ask a case participant to confirm their identity with MFA. Run from a case channel. | | `/dispatch-summary` | If allowed for this case/incident type, will create an AI-generated read-in summary. | -### Contact Information Resolver Plugin +### Contact Information Resolver Plugin {#contact-information-resolver-plugin} -#### API Bot Token +#### API Bot Token {#api-bot-token-1} > The Slack app's bot token necessary to communicate with the Slack API. Slack refers to this as your "Bot User OAuth Access Token" and should be revealed to app collaborators when installing the app. -#### Socket Mode App Token +#### Socket Mode App Token {#socket-mode-app-token-1} > The Slack app's socket mode token provided when socket mode is enabled to authenticate to the WebSocket API. Its value will be ignored if socket mode is not used. -#### Signing Secret +#### Signing Secret {#signing-secret-1} > The secret used to verify signatures included on each HTTP request that Slack sends. Slack refers to this as your "Signing Secret." -#### Profile Department Field Id +#### Profile Department Field Id {#profile-department-field-id} > The profile field ID where Department is mapped. -#### Profile Team Field Id +#### Profile Team Field Id {#profile-team-field-id} > The profile field ID where the Team is mapped. -#### Profile Weblink Field Id +#### Profile Weblink Field Id {#profile-weblink-field-id} > The profile field ID where the weblink is mapped. diff --git a/docs/docs/administration/settings/plugins/configuring-zoom.mdx b/docs/docs/administration/settings/plugins/configuring-zoom.mdx index fd9864e98a5a..bae15af59349 100644 --- a/docs/docs/administration/settings/plugins/configuring-zoom.mdx +++ b/docs/docs/administration/settings/plugins/configuring-zoom.mdx @@ -24,7 +24,7 @@ To recover: Dispatch returns the stored client secret to the UI masked as `**********`, and saving the form writes back whatever it holds. Opening the Zoom plugin to change any other field — the API User Id, say — and saving will overwrite the client secret with those asterisks, and authentication then fails with `Invalid client_id or client_secret`. **Re-enter the Client Secret every time you save this form.** This affects every plugin with a secret field, not just Zoom. ::: -## Creating the Zoom app +## Creating the Zoom app {#creating-the-zoom-app} 1. In the [Zoom App Marketplace](https://marketplace.zoom.us/), sign in as an account admin and choose **Develop → Build App → Server-to-Server OAuth**. (The JWT app type this plugin once required can no longer be created.) 2. Give the app a name, fill in the required basic information, and activate it. @@ -44,33 +44,33 @@ Dispatch returns the stored client secret to the UI masked as `**********`, and A missing scope is not reported when the token is issued — the token is granted and the API call fails afterwards, so add the scopes before configuring Dispatch. 4. From **App Credentials**, copy the **Account ID**, **Client ID** and **Client Secret**. -## Dispatch Configuration +## Dispatch Configuration {#dispatch-configuration} The Zoom plugin is configured in the Dispatch Web UI under Settings -> Project -> Plugins. Add the plugin using the `NEW` button and then edit its configuration by clicking on the three vertical dots. Enter the credentials through that form only. Do not pass them on a command line or place them in a URL — Dispatch stores the client secret in an encrypted column, and either of those would leak it to shell history, process listings or proxy logs. -### Zoom API User Id +### Zoom API User Id {#zoom-api-user-id} > Email or user ID that meetings are created on behalf of. -### Account ID +### Account ID {#account-id} > Account ID of the Server-to-Server OAuth app, from its App Credentials page. -### Client ID +### Client ID {#client-id} > Client ID of the Server-to-Server OAuth app. -### Client Secret +### Client Secret {#client-secret} > Client secret of the Server-to-Server OAuth app. **Treat this as a credential** — anyone holding it can act on the account through the app's scopes. Rotate it in the Marketplace if it is ever exposed. -### Default Meeting Duration (Minutes) +### Default Meeting Duration (Minutes) {#default-meeting-duration-minutes} > Default duration in minutes for conference meetings. Defaults to 1440 minutes (1 day). -## Validating the configuration +## Validating the configuration {#validating-the-configuration} Create a test incident in a project with the plugin enabled and confirm a conference link appears. Any failure — authenticating, or the meeting call itself — is recorded on the incident timeline with the reason Zoom gave, and no conference is attached. @@ -83,7 +83,7 @@ Create a test incident in a project with the plugin enabled and confirm a confer | `This API does not support client credentials for authorization` | Returned by the API, not the token endpoint: a `client_credentials` token was presented to an endpoint requiring account authorization. | | `The Zoom plugin configuration could not be read` | The plugin still holds the retired API Key / API Secret. See the upgrade note above. | -## Notes +## Notes {#notes} - Access tokens live one hour and Zoom issues no refresh token. Dispatch acquires a token per operation and reuses it for the calls that operation makes; tokens are never written to disk. Nothing needs rotating on a schedule apart from the client secret itself, at whatever interval your policy requires. - Zoom rate-limits meeting creation to **100 per day** against the configured API user, and meeting updates to **100 per day per meeting**. The first caps how many conference bridges a deployment can open in 24 hours account-wide; the second caps roster changes on a single long-running incident. Both surface as timeline errors rather than silent failures. diff --git a/docs/docs/administration/settings/plugins/index.mdx b/docs/docs/administration/settings/plugins/index.mdx index 3b4c68bf1097..8fccf51637de 100644 --- a/docs/docs/administration/settings/plugins/index.mdx +++ b/docs/docs/administration/settings/plugins/index.mdx @@ -1,8 +1,8 @@ # Plugins -Before being able to configure and use the plugins, refer to the [CLI](../../cli.mdx#plugins) documentation about installing plugins. +Before being able to configure and use the plugins, refer to the [CLI](../cli#plugins) documentation about installing plugins. -Much of Dispatch's functionality comes from its plugins. The current Dispatch web UI is limited to enabling and disabling plugins on a per-project basis. To make modifications to how plugins behave or are configured, changes must be deployed via the server configuration file. See the [server](../server.mdx) configuration documentation for more information. +Much of Dispatch's functionality comes from its plugins. The current Dispatch web UI is limited to enabling and disabling plugins on a per-project basis. To make modifications to how plugins behave or are configured, changes must be deployed via the server configuration file. See the [server](server) configuration documentation for more information. By default, no plugins are _required_ to create an incident. As you enable plugins, they will be additive to the incident process (e.g., creating slack channels, google docs, etc.) diff --git a/docs/docs/administration/settings/project.mdx b/docs/docs/administration/settings/project.mdx index 5be3a8229227..4c4c7d892e73 100644 --- a/docs/docs/administration/settings/project.mdx +++ b/docs/docs/administration/settings/project.mdx @@ -9,7 +9,7 @@ Every case or incident within Dispatch is tied to a project. The project configu From having their own case or incident types and priorities to providing the team with a view of their metrics. -### When should I create a new project vs using an existing one? +### When should I create a new project vs using an existing one? {#when-should-i-create-a-new-project-vs-using-an-existing-one} Generally, you would create a new project when the teams involved have very little overlap when handling cases or incidents. diff --git a/docs/docs/administration/settings/server.mdx b/docs/docs/administration/settings/server.mdx index 0283a6e21090..be048caee886 100644 --- a/docs/docs/administration/settings/server.mdx +++ b/docs/docs/administration/settings/server.mdx @@ -7,7 +7,7 @@ description: >- # Server -## First Install +## First Install {#first-install} Dispatch uses the same configuration system as [Starlette](https://www.starlette.io/config/). @@ -21,43 +21,43 @@ All config items prefixed with `VITE_` are envvars for the Vue frontend. These v In general, do not include any quotation marks when adding configuration values. ::: -### General +### General {#general} -#### `LOG_LEVEL` \[default: 'WARNING'\] +#### `LOG_LEVEL` \[default: 'WARNING'\] {#log_level-default-warning} > Controls the level of logging the application will perform during operations. Possible values: CRITICAL, ERROR, WARNING, INFO, DEBUG -#### `STATIC_DIR` \[default: 'src/dispatch/static/dispatch/dist'\] +#### `STATIC_DIR` \[default: 'src/dispatch/static/dispatch/dist'\] {#static_dir-default-srcdispatchstaticdispatchdist} > Controls where on the local disk, static content for the Dispatch Web UI should be served. This variable can also be explicitly set to `''` if you wish to serve static content outside of the Dispatch server. -#### `METRIC_PROVIDERS` \[default: ""\] +#### `METRIC_PROVIDERS` \[default: ""\] {#metric_providers-default-} > A comma-separated list of metric providers where Dispatch will send key system metrics. -#### `SECRET_PROVIDER` \[default: None\] +#### `SECRET_PROVIDER` \[default: None\] {#secret_provider-default-none} > Defines the provider to use for configuration secret decryption. Available options are: `kms-secret` and `metatron-secret` -#### `ENV_TAGS` \[default: ""\] +#### `ENV_TAGS` \[default: ""\] {#env_tags-default-} > A comma-separated list of tags that Dispatch will attempt to pull from the environment. For example, the string `foo:bar,baz:blah` will create two tags: `foo` with the environment value for `bar` and `baz` with the environment value for `blah`. -#### `SENTRY_DSN` \[default: none\] +#### `SENTRY_DSN` \[default: none\] {#sentry_dsn-default-none} > Optional configuration for using Sentry to report Dispatch errors. -#### `MJML_PATH` \[default: 'static/dispatch/node_modules/.bin' (relative to the package directory)\] +#### `MJML_PATH` \[default: 'static/dispatch/node_modules/.bin' (relative to the package directory)\] {#mjml_path-default-staticdispatchnode_modulesbin-relative-to-the-package-directory} > Dispatch uses [MJML](https://mjml.io/documentation/) to generate its HTML emails. This package also requires the `node` binary to be available on the standard path (or set in Dispatch's path). Use this variable to adjust the location where Dispatch should look for the `mjml` command. **If you are using the stock docker image of Dispatch you must manually set this field to the default path.** -#### `DISPATCH_UI_URL` +#### `DISPATCH_UI_URL` {#dispatch_ui_url} > URL of the Dispatch's Admin UI, used by messaging to refer to the Admin UI. -### Authentication +### Authentication {#authentication} -#### `DISPATCH_AUTHENTICATION_PROVIDER_SLUG` \['default': dispatch-auth-provider-basic\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_SLUG` \['default': dispatch-auth-provider-basic\] {#dispatch_authentication_provider_slug-default-dispatch-auth-provider-basic} > Used by Dispatch to determine which authentication provider to use; by default, Dispatch ships with a basic authentication provider. A PKCE authentication provider (`dispatch-auth-provider-pkce`) is also available. @@ -65,7 +65,7 @@ In general, do not include any quotation marks when adding configuration values. If you wish to disable authentication set `DISPATCH_AUTHENTICATION_PROVIDER_SLUG=` ::: -#### Configuration for `dispatch-auth-provider-basic` +#### Configuration for `dispatch-auth-provider-basic` {#configuration-for-dispatch-auth-provider-basic} :::warning Today, basic authentication allows self-registration without approval. @@ -75,34 +75,34 @@ Today, basic authentication allows self-registration without approval. For this plugin to work, you need to set `DISPATCH_JWT_SECRET`. ::: -#### `DISPATCH_JWT_SECRET` +#### `DISPATCH_JWT_SECRET` {#dispatch_jwt_secret} > Used by the basic auth provider to mint JWT tokens. -#### `DISPATCH_JWT_ALG` \['default': 'HS256'\] +#### `DISPATCH_JWT_ALG` \['default': 'HS256'\] {#dispatch_jwt_alg-default-hs256} > Used by the basic auth provider to mint JWT tokens. -#### `DISPATCH_JWT_EXP` \['default': 86400 \] +#### `DISPATCH_JWT_EXP` \['default': 86400 \] {#dispatch_jwt_exp-default-86400-} > Used by the basic auth provider to mint JWT tokens and set their expiration. -#### `DISPATCH_JWT_AUDIENCE` +#### `DISPATCH_JWT_AUDIENCE` {#dispatch_jwt_audience} > The `aud` the PKCE provider requires an id token to carry — normally the OIDC > client id. Tokens issued for a different application are rejected. If your > provider sets `aud` and this is unset, every token is rejected. -#### `DISPATCH_JWT_EMAIL_OVERRIDE` +#### `DISPATCH_JWT_EMAIL_OVERRIDE` {#dispatch_jwt_email_override} > Override where Dispatch should find the user email in the idtoken. Defaults to > the `email` claim. A token with no value for the configured claim is rejected. -#### `DISPATCH_AUTHENTICATION_DEFAULT_USER` \['default': dispatch@example.com\] +#### `DISPATCH_AUTHENTICATION_DEFAULT_USER` \['default': dispatch@example.com\] {#dispatch_authentication_default_user-default-dispatchexamplecom} > Used as the default anonymous user when authentication is disabled. -#### Configuration for `dispatch-auth-provider-pkce` +#### Configuration for `dispatch-auth-provider-pkce` {#configuration-for-dispatch-auth-provider-pkce} This is Dispatch's generic OpenID Connect provider. It authenticates the browser with the authorization code flow plus PKCE, and validates the resulting token on @@ -118,13 +118,13 @@ may additionally need `DISPATCH_JWT_EMAIL_OVERRIDE` and `DISPATCH_PKCE_DONT_VERIFY_AT_HASH`, depending on what your provider issues. ::: -#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS` +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS` {#dispatch_authentication_provider_pkce_jwks} > Used by Dispatch's authentication backend to pull the JSON Web Key Set \(JWKS\) public key from the specified provider. > This will likely be the `jwks_uri` URL from your OIDC provider. > This is required when using the `dispatch-auth-provider-pkce` auth provider. -#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_ISSUER` +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_ISSUER` {#dispatch_authentication_provider_pkce_issuer} > The exact `iss` value your provider mints, for example > `https://login.microsoftonline.com/<tenant-id>/v2.0`. Tokens carrying any other @@ -139,24 +139,24 @@ startup when the PKCE provider is selected and this is unset. It has no default that existing deployments keep working, but a new deployment should always set it. ::: -#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS_CACHE_SECONDS` \['default': 300\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS_CACHE_SECONDS` \['default': 300\] {#dispatch_authentication_provider_pkce_jwks_cache_seconds-default-300} > How long the provider's signing keys are cached. Keys are also refetched > immediately when a token arrives with a key id Dispatch has not seen, so a > rotated signing key is picked up without waiting for this to expire. -#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS_TIMEOUT_SECONDS` \['default': 5\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS_TIMEOUT_SECONDS` \['default': 5\] {#dispatch_authentication_provider_pkce_jwks_timeout_seconds-default-5} > Request timeout when fetching the JWKS. If the fetch fails and keys are already > cached, the cached keys keep being used rather than failing every request for > the duration of the provider's outage. -#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_LEEWAY_SECONDS` \['default': 60\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_LEEWAY_SECONDS` \['default': 60\] {#dispatch_authentication_provider_pkce_leeway_seconds-default-60} > Clock skew tolerated when checking `exp`, `nbf` and `iat`. Set to `0` to require > exact agreement with the identity provider's clock. -#### `DISPATCH_PKCE_DONT_VERIFY_AT_HASH` \['default': false\] +#### `DISPATCH_PKCE_DONT_VERIFY_AT_HASH` \['default': false\] {#dispatch_pkce_dont_verify_at_hash-default-false} > Depending on what values your OIDC provider sends, you may need to set this to `true` for the Dispatch backend > to be able to decode the JWT token. Accepts `true`/`false` (or `1`/`0`) only; @@ -168,25 +168,25 @@ the code-for-token exchange this flow uses, so an Entra deployment does not need this setting. ::: -#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL` +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL` {#dispatch_authentication_provider_pkce_open_id_connect_url} > The well-known configuration URL for your OIDC provider, without a trailing slash. Used by the Dispatch > Web UI to authenticate a user via Proof Key Code Exchange \(PKCE\). -#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_CLIENT_ID` +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_CLIENT_ID` {#dispatch_authentication_provider_pkce_client_id} > The client id to send to the OpenID Connect endpoint. -#### `DISPATCH_AUTHENTICATION_PROVIDER_USE_ID_TOKEN` \['default': false\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_USE_ID_TOKEN` \['default': false\] {#dispatch_authentication_provider_use_id_token-default-false} > Use `id_token` instead of default `access_token`. [Details](https://developer.okta.com/docs/reference/api/oidc/#tokens-and-claims) > Depends on the identity provider. -#### Configuration for `dispatch-auth-provider-header` +#### Configuration for `dispatch-auth-provider-header` {#configuration-for-dispatch-auth-provider-header} > Authenticate users based on HTTP request headers. Useful when Dispatch is behind a reverse proxy performing authentication. -#### `DISPATCH_AUTHENTICATION_PROVIDER_HEADER_NAME` \['default': remote-user\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_HEADER_NAME` \['default': remote-user\] {#dispatch_authentication_provider_header_name-default-remote-user} :::info Make sure the reverse proxy strips this header from incoming requests (i.e. user-provided). Failure to do so will result in authentication bypass. @@ -194,21 +194,21 @@ Make sure the reverse proxy strips this header from incoming requests (i.e. user > The HTTP request header to use as the user name, this value is case-insensitive. -#### Configuration for `dispatch-auth-provider-aws-alb` +#### Configuration for `dispatch-auth-provider-aws-alb` {#configuration-for-dispatch-auth-provider-aws-alb} > Authenticate users based on [AWS Application Load Balancer authenticate](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html). -#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_ARN` +#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_ARN` {#dispatch_authentication_provider_aws_alb_arn} > ARN of your Load Balancer, used to validate the signer. > The format is `arn:aws:elasticloadbalancing:region-code:account-id:loadbalancer/app/load-balancer-name/load-balancer-id`. > This is required when using the `dispatch-auth-provider-aws-alb` auth provider. -#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_EMAIL_CLAIM` \['default': email\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_EMAIL_CLAIM` \['default': email\] {#dispatch_authentication_provider_aws_alb_email_claim-default-email} > Override where Dispatch should find the user email in the users claims. -#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_PUBLIC_KEY_CACHE_SECONDS` \['default': 300\] +#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_PUBLIC_KEY_CACHE_SECONDS` \['default': 300\] {#dispatch_authentication_provider_aws_alb_public_key_cache_seconds-default-300} > Override how long Dispatch should cache the public key, used to validate the payload. @@ -216,26 +216,26 @@ Make sure the reverse proxy strips this header from incoming requests (i.e. user Add a ALB listener action without authenticate for `/api/v1/{organization}/events/*` if you want plugins to be public. Plugins determine their own authentication. ::: -### Persistence +### Persistence {#persistence} -#### `DATABASE_HOSTNAME` +#### `DATABASE_HOSTNAME` {#database_hostname} > Dispatch relies on a `Postgres` database. This hostname should point to a supported version of `Postgres` — this project tests against and deploys `18`; there is no supported upgrade path from a pre-`14` cluster. -#### `DATABASE_CREDENTIALS` \[secret: True\] +#### `DATABASE_CREDENTIALS` \[secret: True\] {#database_credentials-secret-true} > Credentials specified in `username:password` format to be used to authenticate to the `postgres` database. -#### `DATABASE_NAME` \[default: 'dispatch'\] +#### `DATABASE_NAME` \[default: 'dispatch'\] {#database_name-default-dispatch} > Allows the user to specify the database name for the `Dispatch` backend. -#### `DATABASE_PORT` \[default: '5432'\] +#### `DATABASE_PORT` \[default: '5432'\] {#database_port-default-5432} > Allows the user to specify the database port for the `Dispatch` backend. -### Models +### Models {#models} -### Incident Cost +### Incident Cost {#incident-cost} Dispatch [calculates](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L279) the cost of an incident by adding up the time participants have spent on each incident role \(e.g., Incident Commander\) and applying an [engagement multiplier](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L266) that's based on the incident role. It also includes time spent on incident review-related activities. Dispatch calculates and publishes the cost for all incidents [every 5 minutes](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/scheduled.py#L257). diff --git a/docs/docs/administration/settings/signal/definition.mdx b/docs/docs/administration/settings/signal/definition.mdx index c652eb3b720d..c63aaec152e9 100644 --- a/docs/docs/administration/settings/signal/definition.mdx +++ b/docs/docs/administration/settings/signal/definition.mdx @@ -2,7 +2,7 @@ Signal Definitions are your starting point for onboarding a new Signal into Dispatch and allow a number of different configuration options. -## Sending Signals to Dispatch +## Sending Signals to Dispatch {#sending-signals-to-dispatch} You can send a signal to Dispatch by making a `POST` request to the `/{organization}/signals/instances` API endpoint. @@ -51,7 +51,7 @@ You can view the full API documentation for the `/instances` endpoint in the [AP ::: -## Creating a Signal Definition +## Creating a Signal Definition {#creating-a-signal-definition} At a high level, you'll need to configure some basic metadata about your `signal` such as the name, description, and variant. You can also configure whether a `signal` should create a case or not. Choosing not to create a case can be useful for contextual signals that diff --git a/docs/docs/administration/settings/signal/engagement-filter.mdx b/docs/docs/administration/settings/signal/engagement-filter.mdx index ee5d7ac95993..2882abee984e 100644 --- a/docs/docs/administration/settings/signal/engagement-filter.mdx +++ b/docs/docs/administration/settings/signal/engagement-filter.mdx @@ -2,7 +2,7 @@ Engagement Filters are used to automate the process of reaching out to a user involved in a specific Signal Instance. Engagement Filters make use of Entity Types that match email addresses for users in your environment and custom message you configure to be sent to those users. Engagement Filters also support multi-factor authentication when validating suspicious behavior. This feature is useful when you want to be confident the user you engaged is actually who they say they are and not a malicious actor. -### Creating an Engagement Filter +### Creating an Engagement Filter {#creating-an-engagement-filter} To create an Engagement Filter, follow these steps: diff --git a/docs/docs/administration/settings/signal/entity-type.mdx b/docs/docs/administration/settings/signal/entity-type.mdx index 485297f421df..cb7d181d2700 100644 --- a/docs/docs/administration/settings/signal/entity-type.mdx +++ b/docs/docs/administration/settings/signal/entity-type.mdx @@ -2,7 +2,7 @@ Entity Types enable the extraction of entities from the raw Signal Instance data. Once extracted, these entities are stored for further use, enabling features like automatic correlations, engagement filters, and signal filters. -### Creating an Entity Type +### Creating an Entity Type {#creating-an-entity-type} To create an Entity Type, follow these steps: diff --git a/docs/docs/administration/settings/signal/filter.mdx b/docs/docs/administration/settings/signal/filter.mdx index 2722d85aa8f8..3ac97c2d99c2 100644 --- a/docs/docs/administration/settings/signal/filter.mdx +++ b/docs/docs/administration/settings/signal/filter.mdx @@ -6,7 +6,7 @@ Signal Filters are used to define how Signals should be grouped together or when To create a Signal Filter, you must first define the Entity Types that will be used to deduplicate or snooze Signals. ::: -## Snooze Filter +## Snooze Filter {#snooze-filter} Snooze filters make use of entities extracted from signals to define when a signal should be snoozed. This feature is useful when an influx of signals is expected for a given period of time (e.g. some known administration activities) and you want to temporarily stop cases from being created. Even when a signal is snoozed it will still be processed and associated entities will be created. @@ -16,7 +16,7 @@ For example, you can create a `Snooze Filter` that will snooze all incoming sign You also have the option to create a `Snooze Filter` without specifying any entities, which will snooze all incoming signals matching that filter. ::: -### Creating a Snooze Filter +### Creating a Snooze Filter {#creating-a-snooze-filter} To create an Snooze Filter, follow these steps: @@ -27,7 +27,7 @@ To create an Snooze Filter, follow these steps: ![](/img/admin-ui-signal-filter-snooze.png) -## Deduplication Filter +## Deduplication Filter {#deduplication-filter} In order to perform signal duplication, a duplication filter must be created. Deduplication filters leverage extracted signal entity types and a sliding time window in order to determine if a signal should be marked as a duplicate. If a match is found, the current signal is marked as duplicate and it is associated with the existing case. @@ -35,7 +35,7 @@ In order to perform signal duplication, a duplication filter must be created. De By default, all Signals are deduplicated over a one hour window unless a custom Deduplication Filter is defined. ::: -### Creating a Deduplication Filter +### Creating a Deduplication Filter {#creating-a-deduplication-filter} To create an Deduplication Filter, follow these steps: diff --git a/docs/docs/administration/settings/templates.mdx b/docs/docs/administration/settings/templates.mdx index 68e6034fa055..7db1c4e445ce 100644 --- a/docs/docs/administration/settings/templates.mdx +++ b/docs/docs/administration/settings/templates.mdx @@ -29,13 +29,13 @@ Enabling evergreen for a template instructs Dispatch to send an email reminder t **Evergreen Reminder Interval:** Number of days that should elapse between reminders sent to the document template owner. -### Case Template +### Case Template {#case-template} A copy of this template is created for each new case on case creation. It contains the current state of the case and is used by the case owner/ assignee to capture facts and findings. - [Example Case Document](https://docs.google.com/document/d/1g1cl9liXG8US0eBnrZYRaeWa7Ek_hoZJ5PPadas44vI) -#### Template Variables +#### Template Variables {#template-variables} The following is a list of available variables that Dispatch will attempt to resolve on document creation. Note: we do not currently re-resolve these. @@ -52,13 +52,13 @@ NOTE: All variables must be enclosed in a `{{}}` - `case_status` - The case's status - `case_storage_weblink` - Link to the storage resource -### Incident Template +### Incident Template {#incident-template} A copy of this template is created for each new incident on incident creation. It contains the current state of the incident and is used by incident participants to share knowledge about the incident. - [Example Incident Document](https://docs.google.com/document/d/1fv--CrGpWJJ4nyPR0N0hq4JchHJPuqsXN4azE9CGQiE) -#### Template Variables +#### Template Variables {#template-variables-1} The following is a list of available variables that Dispatch will attempt to resolve on document creation. Note: we do not currently re-resolve these. @@ -78,25 +78,25 @@ NOTE: All variables must be enclosed in a `{{}}` - `document_weblink` - Link to the incident document (if any) - `ticket_weblink` - Link to the incident ticket (if any) -### Executive Template +### Executive Template {#executive-template} Often during an incident an executive report needs to be drafted that provides a high-level overview of the incident and the current actions that are being carried out. A copy of this template will be created, filled, and stored in the incident storage every time a new executive report is drafted. - [Example Executive Report](https://docs.google.com/document/d/1dab6k14p5ageo5B_d1YlB_zS9hMGHDMXy9RUbIZous4) -### Review Template +### Review Template {#review-template} A copy of this template is automatically created when an incident is marked as stable. It is used by the incident commander and participants for reconciling any incident learnings, discussions, or post-incident tasks. - [Example Incident Review Document](https://docs.google.com/document/d/1MkCTyheZRtKzMxOBhLgh3PrvarERA9Bwo0joM7D9tmg) -### Tracking Template +### Tracking Template {#tracking-template} Some incidents require the tracking of multiple assets, this template is a simple spreadsheet that allows incident participants to collaborate on tabular data. - [Example Incident Tracking Sheet](https://docs.google.com/spreadsheets/d/1Odk4KlL7uMF_yd7OvTOCaPWmtTA_WzFBIA4lMeU5cGY) -### Template Association +### Template Association {#template-association} Case and incident templates can be associated to their corresponding types. This allows our templates to closely match a given case or incident type and provide additional context and direction for those given types. diff --git a/docs/docs/administration/upgrading.mdx b/docs/docs/administration/upgrading.mdx index bb5c9e065af5..aa84f00b22d6 100644 --- a/docs/docs/administration/upgrading.mdx +++ b/docs/docs/administration/upgrading.mdx @@ -13,9 +13,9 @@ Beyond that, upgrades are simple as bumping the version of Dispatch \(which will In some cases, you may want to stop services before doing the upgrade process or avoid intermittent errors. ::: -## Upgrading Dispatch +## Upgrading Dispatch {#upgrading-dispatch} -### Upgrading the package +### Upgrading the package {#upgrading-the-package} The easiest way to upgrade the Dispatch package using `pip`: @@ -27,7 +27,7 @@ You may prefer to install a fixed version rather than the latest, as it will all If you're installing from source code, you may have additional unfulfilled requirements, so take the necessary precautions of testing your environment before committing to the upgrade. -### Running Migrations +### Running Migrations {#running-migrations} Just as during the initial setup, migrations are applied with the upgrade command. @@ -35,7 +35,7 @@ Just as during the initial setup, migrations are applied with the upgrade comman dispatch database upgrade ``` -### Restarting services +### Restarting services {#restarting-services} You'll need to ensure that _all_ of Dispatch's services are restarted after an upgrade. Restarting these services is required because Python loads modules in memory, and code changes will not be reflected until they are restarted. diff --git a/docs/docs/support.mdx b/docs/docs/support.mdx index d6583580a93c..ddbfcdb85ff3 100644 --- a/docs/docs/support.mdx +++ b/docs/docs/support.mdx @@ -7,11 +7,11 @@ description: >- # Support -## General Support +## General Support {#general-support} We provide support via [this repo's issue tracker](https://github.com/helldweller/dispatch/issues). We do our best to respond in a timely manner, but please keep in mind that open source is not a core responsibility of our job and we provide the code and support on a best effort basis. -## Reporting a Security Issue +## Reporting a Security Issue {#reporting-a-security-issue} We ask that you do not report a security issue to our standard GitHub issue tracker. @@ -19,6 +19,6 @@ If you believe you've identified a security issue with `Dispatch`, please report > **Note:** The codebase contains no secret values. Development secrets are generated locally by `docker/dev-setup.sh` into a gitignored `docker/.env`; the committed `docker/.env.example` carries only placeholders. -## Supported Versions +## Supported Versions {#supported-versions} This is a single-maintainer, best-effort project with no SLA, but reports are read and acted on. Bug and security reports are accepted against the **latest tagged release** and the current `main` tip only — see [SECURITY.md](https://github.com/helldweller/dispatch/blob/main/SECURITY.md) for the full policy. diff --git a/docs/docs/user-guide/dashboard/incident.mdx b/docs/docs/user-guide/dashboard/incident.mdx index a1e14a740c94..49a650975a02 100644 --- a/docs/docs/user-guide/dashboard/incident.mdx +++ b/docs/docs/user-guide/dashboard/incident.mdx @@ -5,7 +5,7 @@ sidebar_position: 1 # Incidents -## Aggregated top-line metrics +## Aggregated top-line metrics {#aggregated-top-line-metrics} <div style={{textAlign: 'center'}}> @@ -15,9 +15,9 @@ sidebar_position: 1 These metrics are aggregated across all currently filtered incidents. -## Breakdown on key incident facets +## Breakdown on key incident facets {#breakdown-on-key-incident-facets} -### By Incident Type +### By Incident Type {#by-incident-type} <div style={{textAlign: 'center'}}> @@ -25,7 +25,7 @@ These metrics are aggregated across all currently filtered incidents. </div> -### By Incident Priority +### By Incident Priority {#by-incident-priority} <div style={{textAlign: 'center'}}> @@ -33,7 +33,7 @@ These metrics are aggregated across all currently filtered incidents. </div> -## Forecasting +## Forecasting {#forecasting} Dispatch has the ability to do some _simple_ forecasting. It looks at prior incident history and applies [Exponential Smoothing](https://machinelearningmastery.com/exponential-smoothing-for-time-series-forecasting-in-python/#:~:text=Exponential%20smoothing%20is%20a%20time%20series%20forecasting%20method%20for%20univariate%20data.&text=Exponential%20smoothing%20forecasting%20methods%20are,decreasing%20weight%20for%20past%20observations) to guess how many incidents will be encountered in the future. diff --git a/docs/docs/user-guide/incidents/commander.mdx b/docs/docs/user-guide/incidents/commander.mdx index 6f7f83e7594b..11090c126e45 100644 --- a/docs/docs/user-guide/incidents/commander.mdx +++ b/docs/docs/user-guide/incidents/commander.mdx @@ -4,13 +4,13 @@ description: What to expect as an incident commander. # Commander -## Reporting +## Reporting {#reporting} Within Dispatch, Incident Commanders \(ICs\) are also participants and will receive all of the participant messaging. When resolved as the Incident Commander, you are assigned that Dispatch role, and your identity is propagated. All Slack commands are listed below, or you may view _groups_ of commands relating to [People](#people), [Communications](#communications), [Tasks](#tasks), and [Incident Resources & Metadata](#incident-resources-and-metadata). -## All Slack commands +## All Slack commands {#all-slack-commands} - [`/dispatch-add-timeline-event`](#dispatch-add-timeline-event) - [`/dispatch-assign-role`](#dispatch-assign-role) @@ -35,11 +35,11 @@ All Slack commands are listed below, or you may view _groups_ of commands relati - [`/dispatch-list-signals`](#dispatch-list-signals) - [`/dispatch-summary`](#dispatch-summary) -## People +## People {#people} These commands help manage the people helping resolve the incident. -### /dispatch-assign-role +### /dispatch-assign-role {#dispatch-assign-role} Anyone helping run an incident may play various roles. For example, you may have a scribe or an executive liaison, or you may hand off the incident to a new Incident Commander. At any of these times, use `/dispatch-assign-role` to quickly assign a role to any individual. @@ -51,7 +51,7 @@ It's essential to use this command when handing off responsibility for incident </div> -### /dispatch-engage-oncall +### /dispatch-engage-oncall {#dispatch-engage-oncall} You'll need the help of various teams to resolve an incident. To quickly engage an on-call member of another team, use `/dispatch-engage-oncall` to determine their identity and optionally page them. @@ -61,7 +61,7 @@ You'll need the help of various teams to resolve an incident. To quickly engage </div> -### /dispatch-list-participants +### /dispatch-list-participants {#dispatch-list-participants} Use this command to determine which teams and individuals are engaged in the incident. The output looks like this: @@ -71,7 +71,7 @@ Use this command to determine which teams and individuals are engaged in the inc </div> -### /dispatch-update-participant +### /dispatch-update-participant {#dispatch-update-participant} Participants in an incident, or the Incident Commander, may want to know a participant's area of expertise or their expected contribution to resolving an incident. Use `/dispatch-update-participant` to update the reason a participant was added. The dialog appears like this: @@ -81,11 +81,11 @@ Participants in an incident, or the Incident Commander, may want to know a parti </div> -## Communications +## Communications {#communications} These commands help manage incident communications. -### /dispatch-notifications-group +### /dispatch-notifications-group {#dispatch-notifications-group} An incident notifications group consists of individuals or distribution lists. Manage this group by using `/dispatch-notifications-group.` @@ -95,7 +95,7 @@ An incident notifications group consists of individuals or distribution lists. M </div> -### /dispatch-report-executive +### /dispatch-report-executive {#dispatch-report-executive} Some stakeholders are invested in an incident's progress but aren't expected to be directly involved with the incident. For example, your Chief Financial Officer may want to know of an ongoing security incident regarding financial data but will likely not be directing participants or their actions. To keep external stakeholders such as these informed, use `/dispatch-report-executive` to build and distribute a high-level report. @@ -105,7 +105,7 @@ Some stakeholders are invested in an incident's progress but aren't expected to </div> -### /dispatch-report-incident +### /dispatch-report-incident {#dispatch-report-incident} Use `/dispatch-report-incident` to report a new incident. @@ -115,7 +115,7 @@ Use `/dispatch-report-incident` to report a new incident. </div> -### /dispatch-report-tactical +### /dispatch-report-tactical {#dispatch-report-tactical} Regular tactical reports, such as using the Conditions, Actions, and Needs (CAN) format, are critical to keeping your participants well-informed. Use `/dispatch-report-tactical` to easily create these. @@ -135,7 +135,7 @@ The output in the Slack channel will appear like this: </div> -## Tasks +## Tasks {#tasks} Dispatch provides a lightweight bridge between Google Docs comments assigned as tasks and your Slack incident channel. @@ -149,7 +149,7 @@ It looks like this, in the Incident Document: The following commands help manage these tasks associated with an incident. -### /dispatch-list-my-tasks +### /dispatch-list-my-tasks {#dispatch-list-my-tasks} Any individual who issues the `/dispatch-list-my-tasks` command will see a list of tasks created by or assigned to them. @@ -159,7 +159,7 @@ Any individual who issues the `/dispatch-list-my-tasks` command will see a list </div> -### /dispatch-list-tasks +### /dispatch-list-tasks {#dispatch-list-tasks} Use `/dispatch-list-tasks` to display a temporary message listing all tasks associated with the incident. @@ -169,11 +169,11 @@ Use `/dispatch-list-tasks` to display a temporary message listing all tasks asso </div> -## Incident resources and metadata +## Incident resources and metadata {#incident-resources-and-metadata} These commands help manage incident resources and metadata (data about the incident). -### /dispatch-update-incident +### /dispatch-update-incident {#dispatch-update-incident} This command allows the IC to modify several aspects of the incident without ever leaving the conversation interface. @@ -183,7 +183,7 @@ This command allows the IC to modify several aspects of the incident without eve </div> -### /dispatch-add-timeline-event +### /dispatch-add-timeline-event {#dispatch-add-timeline-event} This command helps you add an event to the incident timeline. You may use local time (derived from your Slack profile) or Coordinated Universal Time (UTC). @@ -193,7 +193,7 @@ This command helps you add an event to the incident timeline. You may use local </div> -### /dispatch-list-workflows +### /dispatch-list-workflows {#dispatch-list-workflows} This command will list all workflows associated with the current incident. @@ -203,7 +203,7 @@ This command will list all workflows associated with the current incident. </div> -### /dispatch-run-workflow +### /dispatch-run-workflow {#dispatch-run-workflow} This command will run a pre-configured workflow and associate its artifacts with the current incident. @@ -213,7 +213,7 @@ This command will run a pre-configured workflow and associate its artifacts with </div> -### /dispatch-create-task +### /dispatch-create-task {#dispatch-create-task} This command will create a task for the current incident. <div style={{textAlign: 'center'}}> @@ -223,7 +223,7 @@ This command will create a task for the current incident. </div> -### /dispatch-create-case +### /dispatch-create-case {#dispatch-create-case} This command will create a case for the current incident. @@ -233,25 +233,25 @@ This command will create a case for the current incident. {/* The sections below have no screenshot yet; capturing one needs a live Slack workspace. See issue #135. */} -### /dispatch-update-case +### /dispatch-update-case {#dispatch-update-case} Run `/dispatch-update-case` from a case's channel to open a modal for its title, description, resolution and resolution reason, assignee, status, type, priority and visibility. A case cannot be escalated from here — the status select deliberately omits `Escalated`. Use [`/dispatch-escalate-case`](#dispatch-escalate-case) instead, which creates the incident the case becomes. -### /dispatch-escalate-case +### /dispatch-escalate-case {#dispatch-escalate-case} Run `/dispatch-escalate-case` from a case's channel to turn it into an incident. The modal opens pre-filled from the case — its title, description and project — so you can accept the defaults or adjust them, then pick the incident's type, priority and severity. Dispatch tells you and does nothing if the case has already been escalated; a case escalates once. -### /dispatch-engage-user +### /dispatch-engage-user {#dispatch-engage-user} Run `/dispatch-engage-user` from a case's channel to ask someone to confirm their identity through your multi-factor provider — the usual case being a report that some account did something its owner may not have done. Pick the person and edit the message they will see, or accept the default. Dispatch adds them to the case if they are not already on it, then sends the prompt and reports the outcome back in the channel. It says so in the channel instead if the person has no account in your Slack workspace. -### /dispatch-list-incidents +### /dispatch-list-incidents {#dispatch-list-incidents} Use `/dispatch-list-incidents` to open a modal listing every incident that is currently active or stable, plus any incident closed in the last 24 hours. Each entry links to the incident in Dispatch and shows its commander, project, status, type, severity, and priority. @@ -259,13 +259,13 @@ Run inside an incident channel, it lists that incident's project. Run anywhere e Restricted incidents are never listed, and the modal shows at most 49 incidents; use the Dispatch web interface if your deployment has more. -### /dispatch-list-signals +### /dispatch-list-signals {#dispatch-list-signals} Use `/dispatch-list-signals` to see which signal definitions send their cases to the conversation you run it from. It opens a modal listing every definition whose case type targets that conversation, showing each one's name and variant alongside a [Snooze](../../administration/settings/signal/filter.mdx#snooze-filter) button that temporarily stops it creating cases. Longer lists are paged 25 at a time. The command takes no arguments. If no case type targets that conversation, the modal tells you so. -### /dispatch-summary +### /dispatch-summary {#dispatch-summary} Use `/dispatch-summary` in an incident or case channel to get an AI-generated read-in summary of what has happened so far. It is most useful when you are pulled in late or take the incident over partway through. The summary is shown only to you, and Dispatch labels it as AI-generated — check it before you act on it. diff --git a/docs/docs/user-guide/incidents/feedback.mdx b/docs/docs/user-guide/incidents/feedback.mdx index 141d7b018f76..fe72a4b5f4af 100644 --- a/docs/docs/user-guide/incidents/feedback.mdx +++ b/docs/docs/user-guide/incidents/feedback.mdx @@ -2,7 +2,7 @@ Dispatch sends a direct message on incident close to all incident participants asking them to rate their satisfaction on how to incident was handled and to provide feedback. Feedback submitted by incident participants is stored and displayed in the feedback section of the UI, and shared with the incident's commander via email on a daily basis. -#### Direct Message +#### Direct Message {#direct-message} <div style={{textAlign: 'center'}}> @@ -10,7 +10,7 @@ Dispatch sends a direct message on incident close to all incident participants a </div> -#### Feedback Modal +#### Feedback Modal {#feedback-modal} <div style={{textAlign: 'center'}}> @@ -18,7 +18,7 @@ Dispatch sends a direct message on incident close to all incident participants a </div> -#### Feedback UI Table +#### Feedback UI Table {#feedback-ui-table} <div style={{textAlign: 'center'}}> diff --git a/docs/docs/user-guide/incidents/forms.mdx b/docs/docs/user-guide/incidents/forms.mdx index 0cea0455cb41..8ccaed73836a 100644 --- a/docs/docs/user-guide/incidents/forms.mdx +++ b/docs/docs/user-guide/incidents/forms.mdx @@ -4,11 +4,11 @@ description: How to create custom incident forms # Forms -## Creating a custom form +## Creating a custom form {#creating-a-custom-form} Within Dispatch, admins can create a custom form under Settings -> (choose Project) -> Incident / Form Types. This brings up a table of existing form types (if any). Click on the NEW button to create a new form type. -### Form schema +### Form schema {#form-schema} The form schema takes a JSON array of form objects of the following type: @@ -26,11 +26,11 @@ The following fields are required for each form object: `type`, `title`, and `na Note: be sure to set the form type to "Enabled" so that it will appear in the forms tab in the incident. -#### Conditionals +#### Conditionals {#conditionals} The `if` attribute can be a complex JavaScript boolean expression. Refer to other form items using the format `$<name>` where `<name>` is the unique name identifier. -##### Example +##### Example {#example} ``` [ @@ -40,23 +40,23 @@ The `if` attribute can be a complex JavaScript boolean expression. Refer to othe ] ``` -## Fill out a form in an incident +## Fill out a form in an incident {#fill-out-a-form-in-an-incident} After an incident is opened, go to the View/Edit panel and select the Forms tab at the top. This view will list all of the forms that have been filled out so far. They can either be in the Draft or Completed state. Users can either edit an existing form or create a new one based on any of the enabled form types created as above. While a form is being completed, the user can **Cancel** to discard any changes, **Save as Draft** to save the filled in information and set as _Draft_, or **Submit** to save and set as _Completed_. -## Attorney review +## Attorney review {#attorney-review} A new tab on the left "Forms" lists all of the _Draft_ and _Completed_ forms for leadership and attorney review. For each form, users can view/edit, delete, and a special **Attorney Review** option. This option shows relevant incident details and the values filled out in the form. It also provides an attorney status dropdown and two new fields for attorney notes and open questions. -## Additional attorney questions +## Additional attorney questions {#additional-attorney-questions} If additional questions are required for the attorney team to assess the information on the form, each form type has the option of asking additional attorney questions. This schema follows the same format as the main form schema. The additional attorney questions will appear only on the Attorney Section when performing the Attorney Review from the Forms page. ![](/img/attorney-section.png) -## Scoring schema +## Scoring schema {#scoring-schema} A risk score can be calculated based on the form responses. The scoring schema is a JSON array of objects of the following type: diff --git a/docs/docs/user-guide/incidents/participant.mdx b/docs/docs/user-guide/incidents/participant.mdx index 2a36d254bb9a..6ccbd111ec35 100644 --- a/docs/docs/user-guide/incidents/participant.mdx +++ b/docs/docs/user-guide/incidents/participant.mdx @@ -4,7 +4,7 @@ description: What to expect as an incident participant. # Participant -## Reporting +## Reporting {#reporting} Dispatch attempts to make reporting incidents as easy as possible. Dispatch provides a dedicated incident report form that users throughout the organization can submit to engage incident-related resources. @@ -30,7 +30,7 @@ Once submitted, the user is presented with all of the incident resources they ne </div> -## During +## During {#during} After an incident is created, Dispatch will engage new participants automatically. Which participants are engaged is determined by rules defined in the Dispatch Admin UI. @@ -50,11 +50,11 @@ Each new participant receives a welcome message \(Email + Slack\) providing them Throughout the incident, Dispatch manages the resources necessary to run your investigation, while also providing reminders and notifications. -## After +## After {#after} After an incident is marked stable, Dispatch continues to help with incident management creating additional resources such as Post Incident Review \(PIRs\) documents. -## Notifications +## Notifications {#notifications} In addition to Dispatch engaging individuals that will be directly responsible for managing the incident, it provides notifications for general awareness throughout the organization. @@ -62,7 +62,7 @@ In addition to Dispatch engaging individuals that will be directly responsible f The new incident notification message includes a "Join" button if "Self-Join" is enabled on the project; this allows individuals to add themselves to the incident \(and its resources\) without involvement from the incident commander. ::: -## Self-service engagement +## Self-service engagement {#self-service-engagement} Often participants will want to "self-subscribe" to incidents given a set of parameters. Dispatch allows individuals to be automatically engaged given these parameters. @@ -72,7 +72,7 @@ Next, modify the individual's engagement by selecting or adding terms or phrases For more documentation of incident engagement see [here](../../administration/settings/contact/index.mdx). -### How it works +### How it works {#how-it-works} For any given set of parameters (incident type, incident priority, title, description, etc.) Dispatch will attempt to engage any individual that has associated with those parameters. Currently, this is an "OR" association between terms. Meaning that if any term is matched, the individual will be pulled into the incident. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index c49c93094565..49b378569a5b 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -41,7 +41,11 @@ const config = { // to replace "en" with "zh-Hans". i18n: { defaultLocale: "en", - locales: ["en"], + locales: ["en", "ru"], + localeConfigs: { + en: { label: "English", htmlLang: "en" }, + ru: { label: "Русский", htmlLang: "ru" }, + }, }, plugins: [ [ @@ -51,6 +55,7 @@ const config = { // Must track `blog: false` in the classic preset below — the plugin // hard-errors at postBuild if indexBlog is on with no blog plugin. indexBlog: false, + language: ["en", "ru"], style: undefined, }, ], @@ -110,6 +115,7 @@ const config = { position: "left", }, + { type: "localeDropdown", position: "right" }, { href: "https://github.com/helldweller/dispatch", position: "right", diff --git a/docs/i18n/ru/code.json b/docs/i18n/ru/code.json new file mode 100644 index 000000000000..5efc389a4344 --- /dev/null +++ b/docs/i18n/ru/code.json @@ -0,0 +1,349 @@ +{ + "theme.ErrorPageContent.title": { + "message": "На странице произошёл сбой.", + "description": "The title of the fallback page when the page crashed" + }, + "theme.BackToTopButton.buttonAriaLabel": { + "message": "Прокрутка к началу", + "description": "The ARIA label for the back to top button" + }, + "theme.blog.archive.title": { + "message": "Архив", + "description": "The page & hero title of the blog archive page" + }, + "theme.blog.archive.description": { + "message": "Архив", + "description": "The page & hero description of the blog archive page" + }, + "theme.blog.paginator.navAriaLabel": { + "message": "Навигация по странице списка блогов", + "description": "The ARIA label for the blog pagination" + }, + "theme.blog.paginator.newerEntries": { + "message": "Следующие записи", + "description": "The label used to navigate to the newer blog posts page (previous page)" + }, + "theme.blog.paginator.olderEntries": { + "message": "Предыдущие записи", + "description": "The label used to navigate to the older blog posts page (next page)" + }, + "theme.blog.post.paginator.navAriaLabel": { + "message": "Навигация по странице поста блога", + "description": "The ARIA label for the blog posts pagination" + }, + "theme.blog.post.paginator.newerPost": { + "message": "Следующий пост", + "description": "The blog post button label to navigate to the newer/previous post" + }, + "theme.blog.post.paginator.olderPost": { + "message": "Предыдущий пост", + "description": "The blog post button label to navigate to the older/next post" + }, + "theme.tags.tagsPageLink": { + "message": "Посмотреть все теги", + "description": "The label of the link targeting the tag list page" + }, + "theme.colorToggle.ariaLabel.mode.system": { + "message": "системная тема", + "description": "The name for the system color mode" + }, + "theme.colorToggle.ariaLabel.mode.light": { + "message": "Светлый режим", + "description": "The name for the light color mode" + }, + "theme.colorToggle.ariaLabel.mode.dark": { + "message": "Тёмный режим", + "description": "The name for the dark color mode" + }, + "theme.colorToggle.ariaLabel": { + "message": "Переключение между темным и светлым режимом (сейчас используется {mode})", + "description": "The ARIA label for the color mode toggle" + }, + "theme.docs.breadcrumbs.navAriaLabel": { + "message": "Навигационная цепочка текущей страницы", + "description": "The ARIA label for the breadcrumbs" + }, + "theme.docs.paginator.navAriaLabel": { + "message": "Страница документа", + "description": "The ARIA label for the docs pagination" + }, + "theme.docs.paginator.previous": { + "message": "Предыдущая страница", + "description": "The label used to navigate to the previous doc" + }, + "theme.docs.paginator.next": { + "message": "Следующая страница", + "description": "The label used to navigate to the next doc" + }, + "theme.docs.tagDocListPageTitle.nDocsTagged": { + "message": "Одна страница|{count} страницы|{count} страниц", + "description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.docs.tagDocListPageTitle": { + "message": "{nDocsTagged} с тегом \"{tagName}\"", + "description": "The title of the page for a docs tag" + }, + "theme.docs.versionBadge.label": { + "message": "Версия: {versionLabel}" + }, + "theme.docs.versions.unreleasedVersionLabel": { + "message": "Это документация для будущей версии {siteTitle} {versionLabel}.", + "description": "The label used to tell the user that he's browsing an unreleased doc version" + }, + "theme.docs.versions.unmaintainedVersionLabel": { + "message": "Это документация {siteTitle} для версии {versionLabel}, которая уже не поддерживается.", + "description": "The label used to tell the user that he's browsing an unmaintained doc version" + }, + "theme.docs.versions.latestVersionSuggestionLabel": { + "message": "Актуальная документация находится на странице {latestVersionLink} ({versionLabel}).", + "description": "The label used to tell the user to check the latest version" + }, + "theme.docs.versions.latestVersionLinkLabel": { + "message": "последней версии", + "description": "The label used for the latest version suggestion link label" + }, + "theme.common.editThisPage": { + "message": "Отредактировать эту страницу", + "description": "The link label to edit the current page" + }, + "theme.common.headingLinkTitle": { + "message": "Прямая ссылка на {heading}", + "description": "Title for link to heading" + }, + "theme.lastUpdated.atDate": { + "message": " {date}", + "description": "The words used to describe on which date a page has been last updated" + }, + "theme.lastUpdated.byUser": { + "message": " от {user}", + "description": "The words used to describe by who the page has been last updated" + }, + "theme.lastUpdated.lastUpdatedAtBy": { + "message": "Последнее обновление{atDate}{byUser}", + "description": "The sentence used to display when a page has been last updated, and by who" + }, + "theme.NotFound.title": { + "message": "Страница не найдена", + "description": "The title of the 404 page" + }, + "theme.navbar.mobileVersionsDropdown.label": { + "message": "Версии", + "description": "The label for the navbar versions dropdown on mobile view" + }, + "theme.tags.tagsListLabel": { + "message": "Теги:", + "description": "The label alongside a tag list" + }, + "theme.admonition.caution": { + "message": "предупреждение", + "description": "The default label used for the Caution admonition (:::caution)" + }, + "theme.admonition.danger": { + "message": "осторожно", + "description": "The default label used for the Danger admonition (:::danger)" + }, + "theme.admonition.info": { + "message": "к сведению", + "description": "The default label used for the Info admonition (:::info)" + }, + "theme.admonition.note": { + "message": "примечание", + "description": "The default label used for the Note admonition (:::note)" + }, + "theme.admonition.tip": { + "message": "подсказка", + "description": "The default label used for the Tip admonition (:::tip)" + }, + "theme.admonition.warning": { + "message": "внимание", + "description": "The default label used for the Warning admonition (:::warning)" + }, + "theme.AnnouncementBar.closeButtonAriaLabel": { + "message": "Закрыть", + "description": "The ARIA label for close button of announcement bar" + }, + "theme.blog.sidebar.navAriaLabel": { + "message": "Навигация по последним постам в блоге", + "description": "The ARIA label for recent posts in the blog sidebar" + }, + "theme.DocSidebarItem.expandCategoryAriaLabel": { + "message": "Развернуть раздел «{label}»", + "description": "The ARIA label to expand the sidebar category" + }, + "theme.DocSidebarItem.collapseCategoryAriaLabel": { + "message": "Свернуть раздел «{label}»", + "description": "The ARIA label to collapse the sidebar category" + }, + "theme.IconExternalLink.ariaLabel": { + "message": "(откроется в новой вкладке)", + "description": "The ARIA label for the external link icon" + }, + "theme.NavBar.navAriaLabel": { + "message": "Основная навигация", + "description": "The ARIA label for the main navigation" + }, + "theme.NotFound.p1": { + "message": "К сожалению, мы не смогли найти запрашиваемую вами страницу.", + "description": "The first paragraph of the 404 page" + }, + "theme.NotFound.p2": { + "message": "Пожалуйста, обратитесь к владельцу сайта, с которого вы перешли на эту ссылку, чтобы сообщить ему, что ссылка не работает.", + "description": "The 2nd paragraph of the 404 page" + }, + "theme.navbar.mobileLanguageDropdown.label": { + "message": "Языки", + "description": "The label for the mobile language switcher dropdown" + }, + "theme.TOCCollapsible.toggleButtonLabel": { + "message": "Содержание этой страницы", + "description": "The label used by the button on the collapsible TOC component" + }, + "theme.blog.post.readMore": { + "message": "Читать дальше", + "description": "The label used in blog post item excerpts to link to full blog posts" + }, + "theme.blog.post.readMoreLabel": { + "message": "Подробнее о {title}", + "description": "The ARIA label for the link to full blog posts from excerpts" + }, + "theme.blog.post.readingTime.plurals": { + "message": "{readingTime} мин. чтения|{readingTime} мин. чтения|{readingTime} мин. чтения", + "description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.CodeBlock.copy": { + "message": "Скопировать", + "description": "The copy button label on code blocks" + }, + "theme.CodeBlock.copied": { + "message": "Скопировано", + "description": "The copied button label on code blocks" + }, + "theme.CodeBlock.copyButtonAriaLabel": { + "message": "Скопировать в буфер обмена", + "description": "The ARIA label for copy code blocks button" + }, + "theme.CodeBlock.wordWrapToggle": { + "message": "Переключить перенос по строкам", + "description": "The title attribute for toggle word wrapping button of code block lines" + }, + "theme.docs.breadcrumbs.home": { + "message": "Главная страница", + "description": "The ARIA label for the home page in the breadcrumbs" + }, + "theme.docs.sidebar.collapseButtonTitle": { + "message": "Свернуть сайдбар", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.collapseButtonAriaLabel": { + "message": "Свернуть сайдбар", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.navAriaLabel": { + "message": "Боковая панель документации", + "description": "The ARIA label for the sidebar navigation" + }, + "theme.docs.sidebar.closeSidebarButtonAriaLabel": { + "message": "Закрыть панель навигации", + "description": "The ARIA label for close button of mobile sidebar" + }, + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": { + "message": "← Перейти к главному меню", + "description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)" + }, + "theme.docs.sidebar.toggleSidebarButtonAriaLabel": { + "message": "Переключить навигационную панель", + "description": "The ARIA label for hamburger menu button of mobile navigation" + }, + "theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": { + "message": "Развернуть меню раздела", + "description": "The ARIA label of the button to expand the mobile dropdown navbar item" + }, + "theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": { + "message": "Свернуть меню раздела", + "description": "The ARIA label of the button to collapse the mobile dropdown navbar item" + }, + "theme.docs.sidebar.expandButtonTitle": { + "message": "Развернуть сайдбар", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.docs.sidebar.expandButtonAriaLabel": { + "message": "Развернуть сайдбар", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "cmfcmf/d-s-l.searchBar.placeholder": { + "message": "Поиск...", + "description": "Placeholder shown in the searchbar" + }, + "cmfcmf/d-s-l.searchBar.clearButtonTitle": { + "message": "Очистить", + "description": "Title of the button to clear the current search input" + }, + "cmfcmf/d-s-l.searchBar.detachedCancelButtonText": { + "message": "Отменить", + "description": "Text of the button to close the detached search window" + }, + "cmfcmf/d-s-l.searchBar.submitButtonTitle": { + "message": "Поиск", + "description": "Title of the button to submit a new search" + }, + "cmfcmf/d-s-l.searchBar.noResults": { + "message": "Результатов не найдено.", + "description": "message shown if no results are found" + }, + "theme.blog.post.plurals": { + "message": "{count} запись|{count} записи|{count} записей", + "description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.blog.tagTitle": { + "message": "{nPosts} с тегом \"{tagName}\"", + "description": "The title of the page for a blog tag" + }, + "theme.blog.author.pageTitle": { + "message": "{authorName} - {nPosts}", + "description": "The title of the page for a blog author" + }, + "theme.blog.authorsList.pageTitle": { + "message": "Authors", + "description": "The title of the authors page" + }, + "theme.blog.authorsList.viewAll": { + "message": "View All Authors", + "description": "The label of the link targeting the blog authors page" + }, + "theme.blog.author.noPosts": { + "message": "This author has not written any posts yet.", + "description": "The text for authors with 0 blog post" + }, + "theme.contentVisibility.unlistedBanner.title": { + "message": "Unlisted page", + "description": "The unlisted content banner title" + }, + "theme.contentVisibility.unlistedBanner.message": { + "message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.", + "description": "The unlisted content banner message" + }, + "theme.contentVisibility.draftBanner.title": { + "message": "Draft page", + "description": "The draft content banner title" + }, + "theme.contentVisibility.draftBanner.message": { + "message": "This page is a draft. It will only be visible in dev and be excluded from the production build.", + "description": "The draft content banner message" + }, + "theme.docs.DocCard.categoryDescription.plurals": { + "message": "{count} элемент|{count} элемента|{count} элементов", + "description": "The default description for a category card in the generated index about how many items this category includes" + }, + "theme.ErrorPageContent.tryAgain": { + "message": "Попробуйте ещё раз", + "description": "The label of the button to try again rendering when the React error boundary captures an error" + }, + "theme.common.skipToMainContent": { + "message": "Перейти к основному содержимому", + "description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation" + }, + "theme.tags.tagsPageTitle": { + "message": "Теги", + "description": "The title of the tag list page" + } +} diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current.json b/docs/i18n/ru/docusaurus-plugin-content-docs/current.json new file mode 100644 index 000000000000..9826c8c24d28 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current.json @@ -0,0 +1,54 @@ +{ + "version.label": { + "message": "Next", + "description": "The label for version current" + }, + "sidebar.adminSidebar.category.Settings": { + "message": "Настройки", + "description": "The label for category 'Settings' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.Incident": { + "message": "Инциденты", + "description": "The label for category 'Incident' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.Case": { + "message": "Кейсы", + "description": "The label for category 'Case' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.Signal": { + "message": "Сигналы", + "description": "The label for category 'Signal' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.Contact": { + "message": "Контакты", + "description": "The label for category 'Contact' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.Data": { + "message": "Данные", + "description": "The label for category 'Data' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.Knowledge": { + "message": "Знания", + "description": "The label for category 'Knowledge' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.settings-plugins": { + "message": "Плагины", + "description": "The label for category 'Plugins' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.Contributing": { + "message": "Разработка (на английском)", + "description": "The label for category 'Contributing' in sidebar 'adminSidebar'" + }, + "sidebar.adminSidebar.category.contributing-plugins": { + "message": "Плагины (на английском)", + "description": "The label for category 'Plugins' in sidebar 'adminSidebar'" + }, + "sidebar.userGuideSidebar.category.Dashboards": { + "message": "Дашборды", + "description": "The label for category 'Dashboards' in sidebar 'userGuideSidebar'" + }, + "sidebar.userGuideSidebar.category.Incidents": { + "message": "Инциденты", + "description": "The label for category 'Incidents' in sidebar 'userGuideSidebar'" + } +} diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/cli.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/cli.mdx new file mode 100644 index 000000000000..ec1bfeed3452 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/cli.mdx @@ -0,0 +1,259 @@ +--- +description: Обзор CLI Dispatch. +--- + +# CLI + +В комплекте с Dispatch идёт полноценный CLI с командами для конфигурации, сервера, планировщика, плагинов, базы данных и оболочки. Здесь мы дадим лишь частичный обзор; полный список команд Dispatch, доступных через CLI, выводит команда `dispatch --help` после установки приложения. + +## Сервер {#server} + +Подкоманда server объединяет все команды, относящиеся к серверу Dispatch. + +```bash +> dispatch server --help develop ⬇ ◼ +Usage: dispatch server [OPTIONS] COMMAND [ARGS]... + + Container for all dispatch server commands. + +Options: + --help Show this message and exit. + +Commands: + config Prints the current config as dispatch sees it. + develop Runs a simple server for development. + routes Prints all available routes. + shell Starts an ipython shell importing our app. + start +``` + +### Config {#config} + +Команда `config` помогает при отладке: она показывает переменные конфигурации так, как их видит сервер \(с учётом переменных окружения, значений по умолчанию и файла .env\). + +```bash +> dispatch server config +> +Key Value +---------------------------------------- ----------------------- +DISPATCH_DOMAIN example.com +STATIC_DIR +METRIC_PROVIDERS spectator-metric +... +``` + +### Develop {#develop} + +Команда `develop` запускает сервер для разработки. Он постоянно следит за изменениями файлов и перезагружается при каждом из них. Удобно сочетать его с уровнем логирования `DEBUG`, как показано ниже. + +```bash +> dispatch server develop --log-level debug +``` + +### Routes {#routes} + +Команда `routes` полезна при разработке. Она показывает, какие адреса сейчас слушает сервер, какие HTTP-методы принимаются и включена ли аутентификация. + +```bash +> dispatch server routes +Path Authenticated Methods +------------------------------------ --------------- --------- +/healthcheck False GET +/documents/ True GET +/documents/{document_id} True GET +/documents/ True POST +... +``` + +### Shell {#shell} + +Команда `shell` полезна при разработке. Она открывает интерактивную оболочку Python с тем же контекстом, что и у самого сервера. + +```bash +> dispatch server shell +``` + +### Start {#start} + +Команда `start` запускает веб-сервер Dispatch, пригодный для продакшена. Это псевдоним веб-сервера [uvicorn](https://www.uvicorn.org/), поэтому ей доступны все параметры и флаги этого сервера. + +```bash +> dispatch server start --help +Usage: dispatch server start [OPTIONS] APP + +Options: + --host TEXT Bind socket to this host. [default: + 127.0.0.1] + --port INTEGER Bind socket to this port. [default: 8000] + --uds TEXT Bind to a UNIX domain socket. + --fd INTEGER Bind to socket from this file descriptor. + --reload Enable auto-reload. + --reload-dir TEXT Set reload directories explicitly, instead + of using the current working directory. + ... +``` + +Чтобы запустить Dispatch, команде start нужно указать, где искать [ASGI](https://asgi.readthedocs.io/en/latest/)-приложение `dispatch`. Например, типичный набор флагов может выглядеть так: + +```bash +> dispatch server start dispatch.main:app --workers 6 --host 127.0.0.1 --port 8000 --proxy-headers +``` + +## Планировщик {#scheduler} + +Команда `scheduler` содержит всю логику планировщика Dispatch. + +```bash +> dispatch scheduler --help +Usage: dispatch scheduler [OPTIONS] COMMAND [ARGS]... + + Container for all dispatch scheduler commands. + +Options: + --help Show this message and exit. + +Commands: + list Prints and runs all currently configured periodic tasks, in... + start Starts the scheduler. +``` + +### List {#list} + +Команда `list` выводит все задачи, зарегистрированные в планировщике. Сейчас периоды планировщика зашиты в код, и изменить их нельзя. + +Вывод ниже — показательный пример, а не полный список: каждая подсистема +из `src/dispatch/*/scheduled.py` (case, case_cost, document, evergreen, +incident, incident_cost, monitor, report, tag, task, term, workflow) +регистрирует собственные задачи; полный актуальный список получите, запустив +команду на своём экземпляре. + +```bash +> dispatch scheduler list +Task Name Period At Time +------------------------------- -------------- --------- +incident-status-report-reminder 1:00:00 +incident-daily-summary 1 day, 0:00:00 18:00:00 +calculate-incident-cost 0:05:00 +incident-task-reminders 1:00:00 +incident-task-sync 0:00:30 +term-sync 1:00:00 +document-term-sync 1 day, 0:00:00 +application-sync 1:00:00 +calculate-cases-response-cost 1:00:00 +case-close-reminder 1 day, 0:00:00 18:00:00 +case-triage-reminder 1 day, 0:00:00 18:00:00 +case-stable-reminder 1 day, 0:00:00 18:00:00 +``` + +### Start {#start-1} + +Команда `start` запускает планировщик, после чего задачи выполняются с заданным периодом. + +```bash +> dispatch scheduler start +Starting scheduler... +``` + +Часто бывает нужно выполнить конкретную задачу немедленно: + +```bash +> dispatch scheduler start incident-status-report-reminder --eager +``` + +## База данных {#database} + +Команда `database` содержит всю логику работы с базой данных Dispatch. + +```bash +> dispatch database --help +Usage: dispatch database [OPTIONS] COMMAND [ARGS]... + + Container for all dispatch database commands. + +Options: + --help Show this message and exit. + +Commands: + downgrade Downgrades database schema to the next newest version. + drop Drops all data in database. + dump Dumps the database via pg_dump. + heads Shows the heads of the database. + history Shows the history of the database. + init Initializes a new database. + merge Combines two revisions. + restore Restores the database via psql. + revision Create new database revision. + stamp Forces the database to a given revision. + upgrade Upgrades database schema to newest version. +``` + +:::info +Примечание: команда database объединяет собственные команды и команды `alembic`. Подробнее о миграциях базы данных через alembic читайте [здесь](https://alembic.sqlalchemy.org/en/latest/). +::: + +### Init {#init} + +Команда `init` берёт чистую базу данных и создаёт таблицы и значения, необходимые для работы Dispatch. + +```bash +> dispatch database init +``` + +### Revision {#revision} + +Команда `revision` — это команда `alembic`, которая создаёт новую ревизию схемы базы данных по моделям приложения. + +Обычно её используют вместе с флагом `--autogenerate`: + +```bash +> dispatch database revision --autogenerate +``` + +### Upgrade/Downgrade {#upgradedowngrade} + +Команды `upgrade` и `downgrade` управляют применением миграций `alembic`: с их помощью базу данных можно двигать по ревизиям вперёд и назад. Команду `upgrade` вам придётся запускать почти после каждой установки новой версии Dispatch. + +```bash +> dispatch database upgrade +``` + +### Restore/Dump {#restoredump} + +Команды `restore` и `dump` позволяют быстро сделать резервную копию базы данных Dispatch и восстановить её. С их помощью можно также загрузить наш [тестовый](https://github.com/helldweller/dispatch/blob/main/data/dispatch-sample-data.dump) набор данных в вашу установку Dispatch. + +Сейчас файл `.dump` должен лежать в `$CWD` и называться `dispatch-backup.dump`. + +## Плагины {#plugins} + +Команда `plugin` содержит всю логику работы с плагинами Dispatch. + +### List {#list-1} + +Команда `list` выводит все доступные плагины. Она помогает понять, какие плагины можно подключить через переменные конфигурации. + +```bash +> dispatch plugins list +Title Slug Version Type Author Description +-------------------------------- ------------------------------ ---------- ----------------- ------------- --------------------------------------------------------- +Dispatch - Document Resolver dispatch-document-resolver 0.1.0 document-resolver Kevin Glisson Uses dispatch itself to resolve incident documents. +Dispatch - Participants dispatch-participants 0.1.0 participant Kevin Glisson Uses dispatch itself to determine participants. +Google Docs - Document google-docs-document 0.1.0 document Kevin Glisson Uses google docs to manage document contents. +Google Group - Participant Group google-group-participant-group 0.1.0 participant_group Kevin Glisson Uses Google Groups to help manage participant membership. +... +``` + +### Install {#install} + +Команда `install` попытается установить все доступные плагины. + +```bash +> dispatch plugins install +INFO:dispatch.common.utils.cli:Attempting to load plugin: dispatch_basic_auth +INFO:dispatch.common.utils.cli:Successfully loaded plugin: dispatch_basic_auth +INFO:dispatch.common.utils.cli:Attempting to load plugin: dispatch_contact +INFO:dispatch.common.utils.cli:Successfully loaded plugin: dispatch_contact +INFO:dispatch.common.utils.cli:Attempting to load plugin: dispatch_document_resolver +... +``` + +Имейте в виду: так плагины лишь становятся доступными. Чтобы включить их, [создайте и настройте экземпляр плагина](settings/plugins) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/faq.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/faq.mdx new file mode 100644 index 000000000000..8d8030ffec5d --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/faq.mdx @@ -0,0 +1,15 @@ +# Частые вопросы + +## Команда «dispatch database upgrade» как будто зависла. {#running-dispatch-database-upgrade-seems-stuck} + +Скорее всего, обновление зависло потому, что какой-то запрос к базе данных держит блокировку, которая нужна миграции. + +Чтобы разобраться, подключитесь к базе данных Dispatch и выполните: + +> SELECT \* FROM pg_locks l INNER JOIN pg_stat_activity s ON \(l.pid = s.pid\) WHERE waiting AND NOT granted; + +Запрос вернёт список запросов, которые сейчас ждут выполнения. Найдите среди них PID запроса, который блокирует миграцию, и выполните: + +> select pg_terminate_backend\(<blocking-pid>\); + +Подробнее: [http://stackoverflow.com/questions/22896496/alembic-migration-stuck-with-postgresql](http://stackoverflow.com/questions/22896496/alembic-migration-stuck-with-postgresql). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/index.mdx new file mode 100644 index 000000000000..bbe865edc24e --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/index.mdx @@ -0,0 +1,16 @@ +--- +title: Введение +sidebar_position: 0 +--- + +# Администрирование + +Все средства администрирования Dispatch собраны в веб-интерфейсе: здесь живёт то, что, скорее всего, будет меняться часто \(то, что меняется реже, задаётся в конфигурационном файле Dispatch\). + +Чтобы открыть настройки Dispatch, найдите пункт меню `Settings` («Настройки») и выберите проект, которым хотите управлять. + +<div style={{textAlign: 'center'}}> + +![настройки](/img/admin-ui-settings.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/installation.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/installation.mdx new file mode 100644 index 000000000000..a399b5033ad5 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/installation.mdx @@ -0,0 +1,278 @@ +--- +sidebar_position: 1 +tags: + - Getting started +--- + +# Установка + +Dispatch работает на нескольких сервисах, и всеми ими управляет `Docker Compose`. + +### Требования {#requirements} + +- [Docker](https://www.docker.com/) 17.05.0+ +- [Docker Compose](https://docs.docker.com/compose/) 1.19.0+ +- Отдельный \(под\)домен для Dispatch \(например, dispatch.yourcompany.com\). +- Не менее 2400 МБ памяти +- 2 ядра CPU + +## Установка сервера Dispatch {#installing-dispatch-server} + +Мы настоятельно рекомендуем устанавливать Dispatch и все его сервисы через Docker. Если вам нужно что-то нестандартное, возьмите этот репозиторий за основу своей установки. Если не хотите использовать наши Docker-образы, Dispatch по-прежнему есть на PyPI, но этот способ мы не рекомендуем: вам придётся восстанавливать всю сборку по основному образу Dispatch. Это не слишком сложно, но времени уйдёт заметно больше, и без шишек не обойдётся. + +Чтобы установить Dispatch из репозитория, склонируйте его локально: + +```bash +git clone https://github.com/Jamyn/dispatch-docker.git +``` + +Перед установкой настоятельно советуем прочитать, [как настроить экземпляр Dispatch](./settings/server.mdx): при изменении настроек образы придётся пересобирать \(`docker-compose build`\). Вы можете скопировать и отредактировать примеры конфигов из репозитория. Если конфигов нет, скрипт установки возьмёт эти примеры как рабочие конфигурации. + +:::info +Примечание: Dispatch не запустится без нескольких обязательных переменных конфигурации. См. пример конфигурационного файла [.env](https://github.com/Jamyn/dispatch-docker/blob/main/.env.example). +::: + +:::info +Примечание: по умолчанию в Dispatch нет никаких данных. Для ознакомления мы подготовили тестовый набор данных, он лежит [здесь](https://github.com/helldweller/dispatch/blob/main/data/dispatch-sample-data.dump). Как его восстановить, читайте [здесь](cli.mdx). +::: + +Для начала запустите скрипт установки: + +```bash +./install.sh +``` + +:::info +Примечание: Docker-сервис `core` больше не нужен после того, как собраны зависящие от него сервисы `web` и `schedule`. +::: + +### Проблема «первого» пользователя {#the-first-user-problem} + +В новой установке Dispatch пользователи должны регистрироваться сами через адрес `/auth/register` в интерфейсе Dispatch. По умолчанию пользователи, зарегистрировавшиеся таким способом, получают обычные права «пользователя» («user»). Получить роль «Владелец» (Owner) через интерфейс напрямую нельзя: других владельцев, которые могли бы выдать доступ, ещё нет. + +Для таких пользователей есть команда CLI, которая назначает пользователю нужную роль: + +```bash +docker exec -it dispatch-web-1 bash +dispatch user update --role owner --organization <name-of-the-organization> <email-address-of-registered-user> +``` + +В файле с тестовыми данными организация по умолчанию называется «default». + +Как только появится один пользователь с ролью «Владелец», он сможет выдавать эту роль другим через интерфейс. + +## Выход в продакшен {#going-to-production} + +Прежде чем разворачивать Dispatch в продакшене, стоит учесть несколько моментов и сделать несколько шагов. + +### Основы {#basics} + +Dispatch хранит и обрабатывает чувствительную информацию, поэтому соблюдайте стандартные практики защиты хоста: + +- Запускайте Dispatch от пользователя с ограниченными правами +- Отключите ненужные сервисы +- Включите удалённое логирование +- Ограничьте доступ к хосту + +### Управление учётными данными {#credential-management} + +Плагинам Dispatch нужны API-токены для работы со сторонними ресурсами. Эти токены хранятся либо в переменной окружения, либо в файле `.env` Dispatch. + +По умолчанию эти строки лежат в открытом виде, но в Dispatch есть хуки, которые позволяют расшифровывать учётные данные при старте сервера. См. параметр конфигурации [Secret Provider](./settings/server.mdx#general). + +### Аутентификация {#authentication} + +Чтобы быстро начать работу, Dispatch предоставляет провайдер аутентификации «Basic», который управляет доступом по паре логин-пароль. По умолчанию этот провайдер разрешает **открытую регистрацию**: учётную запись Dispatch сможет создать любой, у кого есть сетевой доступ к вашему серверу. + +Для более надёжной аутентификации Dispatch предлагает метод «PKCE», через который можно подключить существующие, более серьёзные решения SSO. См. [Провайдер аутентификации](./settings/server.mdx#authentication) + +### TLS/SSL {#tlsssl} + +#### Nginx {#nginx} + +Nginx — популярный выбор для обслуживания Python-проекта: + +- Он быстрый. +- Он лёгкий. +- Конфигурационные файлы простые. + +Nginx не запускает никаких процессов Python; он лишь передаёт внешние запросы серверу на Python. + +Поэтому шага два: + +- Запустить процесс Python. +- Запустить Nginx. + +Что вы получите: + +- Несколько проектов могут слушать порт 80; +- Процессы вашего сайта не будут работать с правами администратора, даже если – пользователь не работает в вашей ОС; + -Возможность управлять процессом Python, не трогая Nginx и другие процессы. Это удобно при обновлениях. + +Вам нужно создать конфигурационный файл Nginx для Dispatch. В GNU/Linux такие файлы обычно лежат в `/etc/nginx/conf.d/`. Назовите его `dispatch.conf`. + +proxy_pass передаёт внешний запрос процессу Python. Порт должен совпадать с тем, который использует процесс Dispatch. + +Несколько настроек помогут сделать работу с сайтом удобнее: + +```nginx +server_tokens off; +add_header X-Frame-Options DENY; +add_header X-Content-Type-Options nosniff; +add_header X-XSS-Protection "1; mode=block"; + +server { + listen 80; + return 301 https://$host$request_uri; +} + +server { + listen 443; + access_log /var/log/nginx/log/dispatch.access.log; + error_log /var/log/nginx/log/dispatch.error.log; + + location /api { + proxy_pass http://127.0.0.1:8000; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; + proxy_redirect off; + proxy_buffering off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + + location / { + root /path/to/dispatch/static/dist; + include mime.types; + index index.html; + } +} +``` + +Nginx будет отдавать favicon и статические файлы — он справляется с этим куда лучше, чем Python. + +Мы рекомендуем включать TLS при развёртывании Dispatch. С учётом назначения Dispatch это, возможно, и так очевидно, но чувствительность данных и того, чем он управляет, делает TLS обязательным. Пример конфига Dispatch, который к тому же терминирует TLS: + +:::info +Некоторые пути придётся подправить в зависимости от того, куда вы установили Dispatch. +::: + +```nginx +server_tokens off; +add_header X-Frame-Options DENY; +add_header X-Content-Type-Options nosniff; +add_header X-XSS-Protection "1; mode=block"; + +server { + listen 80; + return 301 https://$host$request_uri; +} + +server { + listen 443; + access_log /var/log/nginx/log/dispatch.access.log; + error_log /var/log/nginx/log/dispatch.error.log; + + # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate + + ssl_certificate /path/to/signed_cert_plus_intermediates; + ssl_certificate_key /path/to/private_key; + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:50m; + + # Diffie-Hellman parameter for DHE cipher suites, recommended 2048 bits + + ssl_dhparam /path/to/dhparam.pem; + + # modern configuration. tweak to your needs. + + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'; + ssl_prefer_server_ciphers on; + + # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) + + add_header Strict-Transport-Security max-age=15768000; + + # OCSP Stapling --- + + # fetch OCSP records from URL in ssl_certificate and cache them + + ssl_stapling on; + ssl_stapling_verify on; + + ## verify chain of trust of OCSP response using Root CA and Intermediate certs + + ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates; + + resolver <IP DNS resolver>; + + location /api { + proxy_pass http://127.0.0.1:8000; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; + proxy_redirect off; + proxy_buffering off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + + location / { + root /path/to/dispatch/static/dist; + include mime.types; + index index.html; + } +} +``` + +Apache +Пример конфига apache: + +```apache +<VirtualHost \*:443> +... +SSLEngine on +SSLCertificateFile /path/to/signed_certificate +SSLCertificateChainFile /path/to/intermediate_certificate +SSLCertificateKeyFile /path/to/private/key +SSLCACertificateFile /path/to/all_ca_certs + + # intermediate configuration, tweak to your needs + SSLProtocol all -SSLv2 -SSLv3 + SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA + SSLHonorCipherOrder on + + # HSTS (mod_headers is required) (15768000 seconds = 6 months) + Header always set Strict-Transport-Security "max-age=15768000" + ... + +# Set the dispatch DocumentRoot to static/dist + +DocumentRoot /www/dispatch/dispatch/static/dist + +# Uncomment to force http 1.0 connections to proxy + +# SetEnv force-proxy-request-1.0 1 + +#Don't keep proxy connections alive +SetEnv proxy-nokeepalive 1 + +# Only need to do reverse proxy + +ProxyRequests Off + +# Proxy requests to the API to the dispatch service (and sanitize redirects from it) + +ProxyPass "/api" "http://127.0.0.1:8000/api" +ProxyPassReverse "/api" "http://127.0.0.1:8000/api" + +</VirtualHost> +``` + +:::info +Этот конфиг не совсем полный. Если у вас есть рабочий конфиг apache, дайте нам знать! +::: + +В конфигурациях выше заложено и несколько лучших практик развёртывания TLS. Включить HSTS, отключить уязвимые шифры — всё это отличные идеи для развёртывания Dispatch в продакшене. + +Другие варианты настройки SSL: [Mozilla SSL Configuration Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/authentication-entra-id.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/authentication-entra-id.mdx new file mode 100644 index 000000000000..7f597ac25b6b --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/authentication-entra-id.mdx @@ -0,0 +1,245 @@ +--- +description: >- + Настройка аутентификации пользователей Dispatch через Microsoft Entra ID по + OpenID Connect. +--- + +# Аутентификация через Microsoft Entra ID + +Dispatch аутентифицирует пользователей в Microsoft Entra ID через свой универсальный провайдер OpenID +Connect — `dispatch-auth-provider-pkce`. Отдельного плагина для Entra нет, и он не +нужен: браузер выполняет authorization code flow OAuth 2.0 с PKCE в вашем тенанте, +а API Dispatch проверяет полученный **ID-токен** при каждом запросе. + +На этой странице — полная конфигурация для внутреннего деплоя Dispatch в одной +организации. Значение каждого отдельного параметра описано в разделе +[Сервер](server#authentication). + +:::warning +Каждый, кто может войти, получает учётную запись. Dispatch создаёт пользователя с ролью `Member` +при первом же запросе от принятой им личности — ни этапа подтверждения, ни +списка разрешённых нет. Граница тенанта *и есть* граница авторизации, поэтому +`DISPATCH_AUTHENTICATION_PROVIDER_PKCE_ISSUER` ниже на практике обязателен. +См. [Кто может войти](#who-can-sign-in). +::: + +## Создайте регистрацию приложения {#create-the-app-registration} + +В [центре администрирования Microsoft Entra](https://entra.microsoft.com) откройте +**Identity → Applications → App registrations → New registration**. + +| Поле | Значение | +| --- | --- | +| **Name** | `Dispatch` | +| **Supported account types** | **Accounts in this organizational directory only (Single tenant)** | +| **Redirect URI** | Платформа **Single-page application (SPA)**, URI `https://dispatch.example.com/implicit/callback` | + +Запишите **Application (client) ID** и **Directory (tenant) ID** со страницы Overview +регистрации. + +### Поддерживаемые типы учётных записей {#supported-account-types} + +Выберите **single tenant**. В Dispatch нет этапа подтверждения пользователей, поэтому мультитенантная +регистрация означает, что любая рабочая, учебная или личная учётная запись Microsoft в мире +сможет войти и получить учётную запись. Выбирайте multitenant, только если действительно хотите +пускать гостей из других каталогов, и дополните это отдельным механизмом +авторизации — параметр издателя ниже может закрепить только один тенант. + +### Redirect URI {#redirect-uri} + +Redirect URI нужно зарегистрировать на платформе **Single-page application**, +а не **Web**. Именно это заставляет Entra: + +* отдавать CORS-заголовки на конечной точке токена, чтобы браузер мог обменять код, и +* принимать обмен кода без клиентского секрета. + +Если зарегистрировать его как **Web**, при обмене токена вы получите `AADSTS9002326: Cross-origin token redemption +is permitted only for the 'Single-Page Application' client-type`. + +Путь фиксирован: фронтенд Dispatch всегда перенаправляет на `/implicit/callback` +на своём origin и восстанавливает страницу, на которой вы были, из хранилища браузера, поэтому +сколько бы маршрутов ни было в приложении, зарегистрировать нужно только этот один URI. Добавьте +`http://localhost:8080/implicit/callback` вторым URI, если хотите, чтобы локальный +dev-сервер входил через ту же регистрацию. + +### Клиентский секрет {#client-secret} + +**Не создавайте его.** Одностраничное приложение — публичный клиент; Microsoft +документирует, что SPA не должны использовать секреты или сертификаты при обмене +кода авторизации, а Entra отклоняет учётные данные клиента в любом запросе с +заголовком `Origin`. Dispatch его никогда не отправляет, и ему негде его хранить так, чтобы +браузер не мог его прочитать. Код к этому клиенту привязывает PKCE, а не секрет. + +### Области и разрешения {#scopes-and-permissions} + +`openid`, `profile` и `email` — три области OpenID Connect, которые фронтенд +и так запрашивает. Больше ничего. Это делегированные разрешения, не требующие +согласия администратора, и ни одно из них не является разрешением Microsoft Graph: Dispatch берёт +личность пользователя из ID-токена и никогда не обращается к Graph. + +Оставьте в **API permissions** значение `User.Read`, которое Entra добавляет по умолчанию, или удалите его. +Dispatch его не использует. + +### Claims токена {#token-claims} + +Dispatch нужен ровно один claim: адрес электронной почты, по которому идентифицируется пользователь. По умолчанию +он читает `email`, но Entra выдаёт `email` для управляемого пользователя, только если добавить его как +необязательный claim или запросить область `email`, и Microsoft документирует это значение +как изменяемое пользователем и не гарантированно корректное. + +Используйте вместо него `preferred_username`: это имя участника-пользователя (UPN), оно выдаётся +с областью `profile` и контролируется каталогом: + +```text +DISPATCH_JWT_EMAIL_OVERRIDE=preferred_username +``` + +Настраивать необязательные claims не требуется. Если ваши UPN — не маршрутизируемые почтовые +адреса (Dispatch также использует это значение, чтобы сопоставлять людей с инцидентами и +адресовать уведомления), добавьте `email` в **Token configuration → Add optional +claim → ID → email** и оставьте `DISPATCH_JWT_EMAIL_OVERRIDE` незаданным. + +## Настройте Dispatch {#configure-dispatch} + +С `<tenant-id>` и `<client-id>` из регистрации: + +```bash +# Select the OIDC provider +DISPATCH_AUTHENTICATION_PROVIDER_SLUG=dispatch-auth-provider-pkce + +# Backend: which tokens to accept +DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS=https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys +DISPATCH_AUTHENTICATION_PROVIDER_PKCE_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0 +DISPATCH_JWT_AUDIENCE=<client-id> +DISPATCH_JWT_EMAIL_OVERRIDE=preferred_username + +# Frontend: how to obtain one +VITE_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL=https://login.microsoftonline.com/<tenant-id>/v2.0 +DISPATCH_AUTHENTICATION_PROVIDER_PKCE_CLIENT_ID=<client-id> +DISPATCH_AUTHENTICATION_PROVIDER_USE_ID_TOKEN=true +``` + +Пояснения к менее очевидным: + +* **`..._OPEN_ID_CONNECT_URL` — это издатель, без завершающего слеша и без + суффикса `.well-known`.** Фронтенд сам добавляет + `/.well-known/openid-configuration`. +* **`..._USE_ID_TOKEN=true` обязателен, а не желателен.** Без него + фронтенд отправляет в API Dispatch *access*-токен Entra. Когда запрошены только области OIDC, + этот токен выпущен для Microsoft Graph, а не для Dispatch — + Microsoft рекомендует не читать и не проверять токены для API, которым вы не + владеете, а его формат не гарантированно является проверяемым JWT. +* **`DISPATCH_JWT_AUDIENCE` — это client id.** `aud` ID-токена Entra — это + приложение, для которого он выпущен. Если параметр не задан, отклоняется каждый токен. +* Параметры с префиксом `VITE_` читаются при **сборке** фронтенд-бандла, а не + при запуске сервера — см. [Сборка фронтенда](#frontend-build). + +### Ограничение входа вашим тенантом {#restricting-sign-in-to-your-tenant} + +Это делают две вещи, и важны обе: + +1. **Регистрация — single tenant**, поэтому Entra выпускает токен с + вашим `aud` только для пользователей вашего каталога. +2. **`DISPATCH_AUTHENTICATION_PROVIDER_PKCE_ISSUER` закрепляет тенант.** Entra подписывает + токены всех тенантов общим набором ключей — одни и те же key id публикуются на + `/common` и на `discovery/v2.0/keys` отдельного тенанта, — поэтому корректная + подпись доказывает лишь то, что токен пришёл от Microsoft. URL JWKS, привязанный к тенанту, + этого не сужает. Именно проверка издателя связывает токен с вашим каталогом, + и это единственный механизм, который продолжит работать, если регистрацию когда-нибудь + переключат на multitenant. + +Ограничивайте, *какие именно* пользователи тенанта могут входить, средствами Entra, а не +Dispatch: установите **Enterprise applications → Dispatch → Properties → +Assignment required** в **Yes** и назначьте группы, которым нужен доступ. +В Dispatch аналога нет. + +### Сборка фронтенда {#frontend-build} + +Три значения с префиксом `VITE_` компилируются в JavaScript-бандл, поэтому +их изменение означает пересборку фронтенда, а не перезапуск сервера. При +сборке образа контейнера передайте их как аргументы сборки: + +```bash +docker build \ + --build-arg VITE_DISPATCH_AUTHENTICATION_PROVIDER_SLUG=dispatch-auth-provider-pkce \ + --build-arg VITE_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_CLIENT_ID=<client-id> \ + --build-arg VITE_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL=https://login.microsoftonline.com/<tenant-id>/v2.0 \ + --build-arg VITE_DISPATCH_AUTHENTICATION_PROVIDER_USE_ID_TOKEN=true \ + -f docker/Dockerfile . +``` + +Параметры бэкенда — обычные переменные окружения и вступают в силу после +перезапуска. Ни один из них не секрет, поэтому их можно спокойно держать в файле Compose или в логе +сборки образа — клиентского секрета в этой конфигурации нет нигде. + +## Кто может войти {#who-can-sign-in} + +Dispatch заводит пользователя при первом появлении. Первый запрос с принятым ID-токеном +создаёт `DispatchUser` с ролью `Member` в той организации, к которой +обращён запрос; администратор в этом не участвует. `Member` не может администрировать +деплой, но может читать инциденты и кейсы и работать с ними. + +Следовательно: + +* **Ограничивайте доступ в Entra, а не в Dispatch.** Используйте *Assignment required* и + назначение групп в enterprise application. +* **Повышайте роли осознанно.** Выдавайте `Admin` или `Owner` в разделе + **«Настройки» → «Пользователи»** (Settings → Users) или командой + `dispatch user update --role owner --organization <org> <email>`. + +### Существующие пользователи Dispatch {#existing-dispatch-users} + +Пользователи идентифицируются по адресу электронной почты, и с включением Entra это не меняется. +Уже существующая учётная запись — созданная самостоятельной регистрацией через базовую аутентификацию, +администратором или прежним провайдером OIDC — сопоставляется по email и сохраняет +свои роли, проекты и историю, когда тот же адрес впервые входит +через Entra. Миграция или повторное заведение не нужны. + +Обратная сторона: кому бы каталог ни выдал адрес, тот наследует +учётную запись Dispatch с этим адресом. Именно поэтому издатель должен быть закреплён за +тем единственным тенантом, который управляет этими почтовыми ящиками. Прежде чем переключать деплой, +проверьте существующие учётные записи на адреса, которыми ваш тенант не владеет, — внешние +подрядчики, общие почтовые ящики, тестовые учётные записи — и удалите или +переименуйте те, которые не должны доставаться кому попало. + +:::info +Dispatch намеренно не идентифицирует пользователей по неизменяемым `oid`/`sub` Entra. Email — +ключ связи во всём продукте: для участников инцидентов, поиска контактов +и каждого плагина сообщений, — так что непрозрачный идентификатор всё равно пришлось бы +переводить обратно в адрес. Адресу можно доверять благодаря ограничению тенанта, а не +неизменяемости claim. +::: + +## Проверка работы {#verifying-it-works} + +1. Перезапустите сервер (и пересоберите фронтенд) с параметрами выше. +2. Откройте Dispatch. Вас должно перенаправить на `login.microsoftonline.com` и обратно. +3. Проверьте лог сервера при запуске. Провайдер PKCE предупреждает обо всём, что ему + нужно, но не задано, — отсутствующий URL JWKS, издатель или аудитория. + +### Устранение неполадок {#troubleshooting} + +| Симптом | Причина | +| --- | --- | +| `AADSTS9002326`, cross-origin token redemption | Redirect URI зарегистрирован как **Web**; поменяйте на **Single-page application**. | +| Ошибка CORS на `/token` | То же, что выше. | +| Петля перенаправлений или 401 на каждый вызов API после успешного входа | `DISPATCH_AUTHENTICATION_PROVIDER_USE_ID_TOKEN` не равен `true`, поэтому отправляется access-токен Graph. | +| 401 с *Token rejected: Invalid audience* в логе | `DISPATCH_JWT_AUDIENCE` не задан или не равен client id. | +| 401 с *Token rejected: Invalid issuer* | Tenant id в `..._PKCE_ISSUER` не совпадает с тенантом, через который выполнен вход. | +| 401 с *Token carries no 'email' claim* | Задайте `DISPATCH_JWT_EMAIL_OVERRIDE=preferred_username` или добавьте необязательный claim `email`. | +| `AADSTS50011`, redirect URI mismatch | Зарегистрированный URI должен быть в точности origin деплоя плюс `/implicit/callback`. | + +## Возврат к другому провайдеру {#reverting-to-another-provider} + +В базе данных откатывать нечего — вход через Entra создаёт обычных +пользователей Dispatch. Чтобы вернуться к базовой аутентификации, задайте + +```bash +DISPATCH_AUTHENTICATION_PROVIDER_SLUG=dispatch-auth-provider-basic +DISPATCH_JWT_SECRET=<secret> +``` + +пересоберите фронтенд с соответствующим `VITE_DISPATCH_AUTHENTICATION_PROVIDER_SLUG` +и перезапустите. Учётные записи, заведённые через Entra, остаются, но были созданы без +рабочего пароля, поэтому каждому пользователю нужен сброс пароля от владельца, прежде чем он сможет +снова войти. Удалите регистрацию приложения в Entra, когда она больше не нужна. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-priority.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-priority.mdx new file mode 100644 index 000000000000..98d88c63d3d5 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-priority.mdx @@ -0,0 +1,21 @@ +# Приоритет кейса + +Помимо типов кейсов, Dispatch позволяет задать приоритет кейса. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-case-priorities.png) + +</div> + +**Название (Name):** название приоритета кейса, которое видит пользователь. + +**Описание:** описание приоритета кейса, которое видит пользователь. + +**Порядок отображения (View Order):** порядок, в котором приоритет выводится в меню и выпадающих списках. + +**Цвет (Color):** цвет приоритета кейса в интерфейсе. + +**Приоритет кейса по умолчанию:** если заявитель кейса не указал приоритет, будет использован приоритет по умолчанию. Включите эту настройку, чтобы этот приоритет кейса стал приоритетом по умолчанию. + +**Включён:** включён ли этот приоритет кейса. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-severity.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-severity.mdx new file mode 100644 index 000000000000..25cbc2d8f06a --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-severity.mdx @@ -0,0 +1,21 @@ +# Серьёзность кейса + +Помимо типов кейсов, Dispatch позволяет задать серьёзность кейса. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-case-severities.png) + +</div> + +**Название (Name):** название серьёзности кейса, которое видит пользователь. + +**Описание:** описание серьёзности кейса, которое видит пользователь. + +**Порядок отображения (View Order):** порядок, в котором серьёзность выводится в меню и выпадающих списках. + +**Цвет (Color):** цвет серьёзности кейса в интерфейсе. + +**Серьёзность кейса по умолчанию:** если заявитель кейса не указал серьёзность, будет использована серьёзность по умолчанию. Включите эту настройку, чтобы эта серьёзность кейса стала серьёзностью по умолчанию. + +**Включён:** включена ли эта серьёзность кейса. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-type.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-type.mdx new file mode 100644 index 000000000000..db8a2aecb351 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/case-type.mdx @@ -0,0 +1,29 @@ +# Типы кейсов + +Dispatch позволяет классифицировать кейсы: вы определяете типы кейсов и привязываете их к различным ресурсам Dispatch (например, к шаблонам, дежурным службам и типам инцидентов). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-case-types.png) + +</div> + +**Название (Name):** название типа кейса, которое видит пользователь. + +**Описание:** описание типа кейса, которое видит пользователь. + +**Видимость:** позволяет указать, насколько виден будет кейс этого типа. Примечание: сейчас этот параметр не используется. + +**Шаблон кейса:** позволяет создать новый или привязать существующий шаблон документа кейса к типу кейса. + +**Дежурная служба:** позволяет привязать существующую дежурную службу, по которой будет определяться владелец кейса. + +**Тип инцидента:** тип инцидента, который будет создан и связан с кейсом, если кейс этого типа переведут в статус «Эскалирован» (Escalated). + +**Исключить из метрик (Exclude From Metrics):** включите эту настройку, чтобы исключить все кейсы этого типа из метрик (например, тестовые кейсы). + +**Тип кейса по умолчанию:** если создатель кейса не указал тип кейса, используется тип кейса по умолчанию. Включите эту настройку, чтобы этот тип кейса стал типом по умолчанию. + +**Включён:** включён ли тип кейса. + +**Метаданные плагина (Plugin Metadata):** позволяет задавать пары «ключ — значение» и передавать их плагинам. Например, создавать тикеты в разных проектах Jira в зависимости от типа кейса. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/index.mdx new file mode 100644 index 000000000000..b661a2405312 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/case/index.mdx @@ -0,0 +1,9 @@ +--- +sidebar_position: 4 +--- + +# Кейс + +Кейсы нужны для разбора событий, которые не дотягивают до уровня инцидента, но при необходимости могут быть эскалированы до инцидента. Если привязать тип кейса к типу инцидента и эскалировать кейс, Dispatch автоматически создаст инцидент и свяжет их между собой. + +Хотя у Dispatch есть твёрдое мнение о том, _как_ вести кейсы, он оставляет немало свободы. Ниже описаны разделы, которые позволяют подстроить работу с кейсами под вашу организацию. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/index.mdx new file mode 100644 index 000000000000..dc74beb909f7 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/index.mdx @@ -0,0 +1,5 @@ +--- +sidebar_position: 5 +--- + +# Контакты diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/individual.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/individual.mdx new file mode 100644 index 000000000000..9e9f58d14c79 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/individual.mdx @@ -0,0 +1,21 @@ +# Человек + +В Dispatch «люди» (Individuals) — это идентификаторы внутренних или внешних людей. Обычно в организации уже есть полноценный внутренний каталог учётных записей пользователей. Dispatch не стремится заменить эти хранилища: он хранит лишь облегчённое представление о людях, чтобы связывать их с инцидентами для фильтрации и метрик. + +Команды реагирования на инциденты часто ведут списки контактов и инструкции (runbook), в которых указано, к кому обращаться при инциденте. Dispatch берёт это на себя и сам подключает нужных людей к инциденту. Если назначить человеку термины, типы или приоритеты инцидентов, Dispatch сразу добавит его в инцидент \(если это внутренний сотрудник\) или предложит с ним связаться \(если внешний\). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-contacts-individuals.png) + +</div> + +**Имя (Name):** имя человека. + +**Эл. почта (Email):** адрес электронной почты человека. + +**Компания (Company):** компания, к которой относится человек. + +#### Вовлечение {#engagement} + +Помимо полей о самом человеке, Dispatch позволяет связать его с другими объектами Dispatch. Например, если вы хотите привлекать человека ко всем инцидентам определённого приоритета, свяжите этот приоритет с человеком. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/service.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/service.mdx new file mode 100644 index 000000000000..f3a1ea65a6cc --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/service.mdx @@ -0,0 +1,23 @@ +# Сервис + +Как и в случае с `Teams`, за приложение или сервис часто отвечает группа людей (команда), которую нужно подключать к инциденту. Но в таких ситуациях мы не хотим вовлекать _всю_ команду — только того, кто сейчас дежурит по этому сервису. `Services` позволяют Dispatch находить таких людей через сторонние дежурные службы (например, PagerDuty, OpsGenie). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-contacts-services.png) + +</div> + +**Название (Name):** название сервиса. + +**Описание:** описание сервиса. + +**Плагин:** плагин сервиса, с помощью которого Dispatch будет определять дежурного. + +**Внешний идентификатор (External Id):** внешний идентификатор, по которому Dispatch и выбранный плагин определяют дежурного. + +**Включён:** флаг, показывающий, активен ли этот сервис. + +#### Вовлечение {#engagement} + +Помимо полей сервиса, Dispatch позволяет связать сервис с другими объектами Dispatch. Например, если вы хотите привлекать сервис ко всем инцидентам определённого приоритета, свяжите этот приоритет с сервисом. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/team.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/team.mdx new file mode 100644 index 000000000000..f146d058d5df --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/contact/team.mdx @@ -0,0 +1,19 @@ +# Команда + +Как и в случае с `Individuals`, во время инцидента часто нужно подключать и уведомлять группы людей (команды). Dispatch ведёт учёт таких групп \(как правило, это списки рассылки команд\) и служит единым хранилищем этих контактных данных. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-contacts-teams.png) + +</div> + +**Название (Name):** название команды. + +**Эл. почта (Email):** адрес электронной почты команды. + +**Компания (Company):** компания, к которой относится команда. + +#### Вовлечение {#engagement} + +Помимо полей о самой команде, Dispatch позволяет связать команду с другими объектами Dispatch. Например, если вы хотите привлекать всю команду ко всем инцидентам определённого приоритета, свяжите этот приоритет с командой. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/cost_model.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/cost_model.mdx new file mode 100644 index 000000000000..67b34659aa23 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/cost_model.mdx @@ -0,0 +1,105 @@ +# Модель затрат + +Модель затрат — функция, которая позволяет командам оценивать стоимость реагирования на каждый инцидент в зависимости от его типа. Пользователи могут по желанию создавать и применять собственные расчёты затрат для каждого типа инцидента на основе активности участников. Модели затрат применяются к инцидентам автоматически — по типу инцидента. + +Если типу инцидента не назначена отдельная модель затрат, при расчёте стоимости инцидента используется классическая модель по умолчанию. См. [Тип затрат инцидента](./incident/incident-cost-type.mdx#calculating-incident-cost). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-cost-model.png) + +</div> + +## Ключевые возможности {#key-features} + +### Настраиваемые модели затрат {#customizable-cost-models} +Пользователи могут задавать собственные модели затрат исходя из рабочих процессов и инструментов своей организации. Такую модель можно подобрать под каждый тип инцидента, что даёт гибкий подход к расчёту затрат. Модель затрат для типа инцидента можно изменить в любой момент. Когда модель затрат типа инцидента меняется или инцидент меняет тип, вся дальнейшая активность участников оценивается уже по новой модели. + +### Отслеживание через плагины {#plugin-based-tracking} +Пользователи могут отслеживать затраты в уже привычных инструментах с помощью системы отслеживания на основе плагинов. Пользователи сами выбирают, какие плагины и какие именно события плагинов учитывать, — это даёт точечный подход к расчёту затрат. + +### Назначение трудозатрат {#effort-assignment} +Для каждой отслеживаемой активности пользователи могут назначить измеримую величину трудозатрат — в секундах рабочего времени. Так стоимость инцидента оценивается точнее. + +### Расчёт стоимости инцидента {#incident-cost-calculation} +Стоимость инцидента рассчитывается по модели затрат и назначенным трудозатратам для каждой отслеживаемой активности участников. Это помогает понять, сколько ресурсов ушло на инцидент и во что он обошёлся. + + +## Поддерживаемые сейчас события плагинов {#currently-supported-plugin-events} + +### Slack: активность в канале {#slack-channel-activity} +Это событие отслеживает активность в определённом канале Slack. Периодически опрашивая сообщения канала, оно собирает сведения об активности и вовлечённости каждого участника. + +### Slack: активность в треде {#slack-thread-activity} +Это событие отслеживает активность в определённом треде Slack. Периодически опрашивая ответы в треде, оно собирает сведения об активности и вовлечённости каждого участника. + + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-edit-cost-model.png) + +</div> + +## Примеры расчёта затрат {#cost-calculation-examples} + +Ниже мы показываем работу модели затрат на двух примерах. Они основаны на следующих значениях: + +<b>Модель затрат 1</b> + +| Событие плагина | Время реакции (секунды) +| ------------ | ------------- +| Активность в канале Slack | 300 + +Почасовую ставку сотрудника можно изменить в полях `Annual Employee Cost` и `Business Year Hours` в [настройках проекта](./project.mdx). В этих примерах мы используем такое значение: +``` +hourly_rate = 100 +``` + +#### Пример 1 {#example-1} + +Рассмотрим такую активность в канале Slack для `Incident 1`: + +| Метка времени активности в канале Slack | Участник +| ------------ | ------------- +| 100 | Cookie Doe +| 200 | Nate Flex + +В результате будет записана следующая активность участников: + +| Участник | started_at | ended_at | Событие плагина | Инцидент +| ------------ | ------------- | ------------- | ------------- | ------------- +| Cookie Doe | 100 | 400 | Активность в канале Slack | Incident 1 +| Nate Flex | 200 | 500 | Активность в канале Slack | Incident 1 + + +Стоимость инцидента затем рассчитывается так: + +``` +( (400 - 100) + (500 - 200) ) / SECONDS_IN_HOUR * hourly_rate = $16.67 +``` + +#### Пример 2 {#example-2} + +Рассмотрим такую активность в канале Slack для `Incident 2`: + +| Метка времени активности в канале Slack | Участник +| ------------ | ------------- +| 100 | Cookie Doe +| 150 | Cookie Doe +| 200 | Nate Flex +| 500 | Cookie Doe + +В результате будет записана следующая активность участников: + +| Участник | started_at | ended_at | Событие плагина | Инцидент +| ------------ | ------------- | ------------- | ------------- | ------------- +| Cookie Doe | 100 | 450 | Активность в канале Slack | Incident 2 +| Nate Flex | 200 | 500 | Активность в канале Slack | Incident 2 +| Cookie Doe | 500 | 800 | Активность в канале Slack | Incident 2 + + +Стоимость инцидента затем рассчитывается так: + +``` +( (450 - 100) + (500 - 200) + (800 - 500) ) / SECONDS_IN_HOUR * hourly_rate = $26.39 +``` diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/data-format.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/data-format.mdx new file mode 100644 index 000000000000..f276567d4318 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/data-format.mdx @@ -0,0 +1,11 @@ +# Форматы данных + +Источники данных не всегда однородны. Часто полезно понимать, в каком формате хранятся данные конкретного источника. Здесь Dispatch позволяет определить распространённые форматы данных, которые используют источники в вашем окружении. + +Примеры форматов данных: + +- JSON +- CSV +- Syslog +- XML +- Нестандартный diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/environment.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/environment.mdx new file mode 100644 index 000000000000..c04a68a086b9 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/environment.mdx @@ -0,0 +1,10 @@ +# Окружение + +У источников данных часто есть окружение, к которому они относятся. Например, один набор данных может содержать сведения только из боевого (production) аккаунта. При реагировании на инциденты и использовании источников данных в расследовании важно понимать, какую область покрывает источник. + +Примеры окружений источника данных: + +- Production +- Staging +- Testing +- Development diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/index.mdx new file mode 100644 index 000000000000..0448420dbe49 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/index.mdx @@ -0,0 +1,3 @@ +# Данные + +Помимо оркестрации инцидентов, Dispatch умеет собирать каталог данных, которые помогают разрешать инциденты. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/status.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/status.mdx new file mode 100644 index 000000000000..5ef4c6d8cc9f --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/status.mdx @@ -0,0 +1,10 @@ +# Статус + +Когда источник данных используется в ходе расследования, нужно понимать текущее состояние этой базы данных. Здесь Dispatch позволяет определить собственные статусы источников данных. + +Примеры статусов: + +- Production +- Testing +- Staging +- Deprecated diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/transport.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/transport.mdx new file mode 100644 index 000000000000..7756e56009a4 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/transport.mdx @@ -0,0 +1,12 @@ +# Транспорт + +Позволяет определить собственные транспортные уровни для источников данных. + +Примеры транспортов источников: + +- REST API +- Syslog +- Hive +- S3 +- Kafka +- Kinesis diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/type.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/type.mdx new file mode 100644 index 000000000000..e2b4a9da1815 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/data/type.mdx @@ -0,0 +1,10 @@ +# Тип + +Чтобы получить доступ к источнику данных или выполнить к нему запрос, вам может понадобиться работать с несколькими разными системами. Тип источника обозначает технологию или систему, с которой он связан теснее всего. + +Примеры типов источника данных: + +- Hive +- ES (ElasticSearch) +- BigQuery +- Splunk diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-cost-type.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-cost-type.mdx new file mode 100644 index 000000000000..4648d4f27c01 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-cost-type.mdx @@ -0,0 +1,25 @@ +# Типы затрат на инцидент + +Dispatch позволяет определить типы затрат на инцидент. Затем эти типы используются при добавлении и редактировании затрат по инцидентам. Каждые 5 минут Dispatch рассчитывает стоимость реагирования для всех инцидентов и сохраняет результат в тип затрат по умолчанию. Рекомендуем создать хотя бы тип затрат на реагирование и сделать его типом по умолчанию, чтобы пользоваться этой полезной возможностью. Список типов затрат на инцидент (или форм потерь, Forms of Loss), который рекомендует институт Factor Analysis of Information Risk (FAIR), доступен [здесь](https://www.fairinstitute.org/blog/a-crash-course-on-capturing-loss-magnitude-with-the-fair-model). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-cost-types.png) + +</div> + +**Название (Name):** название типа затрат на инцидент, которое видит пользователь. + +**Описание:** описание типа затрат на инцидент, которое видит пользователь. + +**Категория (Category):** форма потерь (Form of Loss, FOL) или категория по методике Factor Analysis of Information Risk (FAIR). + +**По умолчанию:** является ли этот тип затрат на инцидент типом по умолчанию. + +**Редактируемый (Editable):** можно ли редактировать этот тип затрат. + +### Расчёт стоимости инцидента {#calculating-incident-cost} + +Dispatch [рассчитывает](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L279) стоимость инцидента, суммируя время, которое участники провели в каждой роли в инциденте \(например, командира инцидента\), и применяя [множитель вовлечённости](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L266), зависящий от роли в инциденте. Также учитывается время, потраченное на работу над разбором инцидента. Dispatch рассчитывает и публикует стоимость всех инцидентов [каждые 5 минут](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/scheduled.py#L257). + +Параметры расчёта стоимости инцидента можно настроить отдельно для каждого проекта — отредактируйте проект [здесь](../project.mdx) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-priority.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-priority.mdx new file mode 100644 index 000000000000..008e1d909f40 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-priority.mdx @@ -0,0 +1,27 @@ +# Приоритет инцидента + +Помимо типов инцидентов, Dispatch позволяет задать _приоритет_ инцидента. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-priorities.png) + +</div> + +**Название (Name):** название приоритета инцидента, которое видит пользователь. + +**Описание:** описание приоритета инцидента, которое видит пользователь при регистрации инцидента. + +**Порядок отображения (View Order):** порядок, в котором приоритет выводится в меню и выпадающих списках. + +**Напоминание о тактическом отчёте (Tactical Report Reminder):** число часов между напоминаниями. + +**Напоминание об отчёте для руководства (Executive Report Reminder):** число часов между напоминаниями. + +**Вызывать командира (Page Commander):** гарантирует, что командира инцидента вызовут по всем инцидентам с этим приоритетом (если это позволяют настроенная служба вызова и плагин). + +**Цвет (Color):** цвет приоритета инцидента в интерфейсе. + +**Приоритет инцидента по умолчанию:** если заявитель инцидента не указал приоритет, будет использован приоритет по умолчанию. Включите эту настройку, чтобы этот приоритет инцидента стал приоритетом по умолчанию. + +**Включён:** включён ли этот приоритет инцидента. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-type.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-type.mdx new file mode 100644 index 000000000000..78362d3ceae5 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/incident-type.mdx @@ -0,0 +1,33 @@ +# Типы инцидентов + +Dispatch позволяет классифицировать инциденты: вы определяете типы инцидентов и привязываете их к различным ресурсам Dispatch (например, к шаблонам). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-types.png) + +</div> + +**Название (Name):** название типа инцидента, которое видит пользователь. + +**Описание:** описание типа инцидента, которое видит пользователь. + +**Видимость:** позволяет указать, насколько виден будет инцидент этого типа. Например, если выбрано `Open` («Открытый»), уведомления об инциденте этого типа будут отправляться при создании и обновлении инцидента, а обновления попадут в ежедневные отчёты по инцидентам. Все пользователи Dispatch смогут видеть инциденты этого типа в веб-интерфейсе независимо от роли. Кроме того, когда инцидент помечен как закрытый, Dispatch использует указанный домен Google, чтобы открыть доступ к папке инцидента и её содержимому всей организации. Если же выбрано `Restricted` («Ограниченный»), инциденты этого типа не попадут в уведомления, не будут видны пользователям Dispatch с ролью `member` в веб-интерфейсе, и Dispatch не откроет папку инцидента и её содержимое всей организации. По умолчанию выбрано `Open`. + +**Шаблон инцидента:** позволяет создать новый или привязать существующий шаблон документа инцидента к типу инцидента. + +**Шаблон отчёта для руководства (Executive Template):** позволяет создать новый или привязать существующий шаблон документа отчёта для руководства к типу инцидента. + +**Шаблон разбора (Review Template):** позволяет создать новый или привязать существующий шаблон документа разбора инцидента к типу инцидента. + +**Шаблон отслеживания (Tracking Template):** позволяет создать новый или привязать существующий шаблон таблицы отслеживания инцидента к типу инцидента. + +**Исключить из метрик (Exclude From Metrics):** включите эту настройку, чтобы исключить все инциденты этого типа из метрик (например, инциденты «Симуляция» или «Тест»). + +**Тип инцидента по умолчанию:** если заявитель инцидента не указал тип инцидента, используется тип по умолчанию. Включите эту настройку, чтобы этот тип инцидента стал типом по умолчанию. + +**Включён:** включён ли тип инцидента. + +**Метаданные плагина (Plugin Metadata):** позволяет задавать пары «ключ — значение» и передавать их плагинам. Например, создавать тикеты в разных проектах Jira в зависимости от типа инцидента. + +**Модель затрат:** позволяет определить, как рассчитывать стоимость реагирования на инцидент. Если у типа инцидента нет модели затрат, при расчёте затрат используется классическая модель по умолчанию. См. [Модель затрат](../cost_model.mdx). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/index.mdx new file mode 100644 index 000000000000..777e6eaf0f45 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/index.mdx @@ -0,0 +1,7 @@ +--- +sidebar_position: 3 +--- + +# Инцидент + +Хотя у Dispatch есть твёрдое мнение о том, _как_ вести инциденты, он оставляет немало свободы. Ниже описаны разделы, которые позволяют подстроить работу с инцидентами под вашу организацию. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/notification.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/notification.mdx new file mode 100644 index 000000000000..7b635982a78a --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/notification.mdx @@ -0,0 +1,21 @@ +# Уведомление + +Уведомления позволяют указать, кому отправлять уведомления об инцидентах (помимо непосредственных участников). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-notifications.png) + +</div> + +**Название (Name):** название, которое увидит пользователь. + +**Описание:** описание, которое видит пользователь при просмотре уведомления. + +**Тип (Type):** тип плагина, через который отправляется уведомление (эл. почта или канал обсуждения). + +**Получатель (Target):** адресат уведомления, подходящий выбранному типу плагина (например, имя канала Slack без `#` или адрес электронной почты). + +**Фильтры (Filters):** фильтр поиска, по которому определяется, когда нужно отправить уведомление. + +**Включён:** включено ли уведомление. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/workflow.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/workflow.mdx new file mode 100644 index 000000000000..a69ee02ff363 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/incident/workflow.mdx @@ -0,0 +1,21 @@ +# Рабочие процессы + +Рабочие процессы позволяют расширять Dispatch, запуская вашу автоматизацию реагирования. Сейчас Dispatch не умеет создавать рабочие процессы сам. Вместо этого он позволяет запускать из Dispatch уже существующие рабочие процессы. Их выполнение мы доверяем внешним инструментам оркестрации, а Dispatch отслеживает статус рабочего процесса и полученные артефакты. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-workflows.png) + +</div> + +**Название (Name):** название, которое увидит пользователь. + +**Описание:** описание, которое видит пользователь при просмотре рабочего процесса. + +**Идентификатор ресурса (Resource Id):** _внешний_ идентификатор ресурса, по которому Dispatch связывает рабочий процесс с внешней системой. + +**Плагин:** плагин, который находит и выполняет этот рабочий процесс. ПРИМЕЧАНИЕ: прежде чем привязывать плагин к рабочему процессу, его нужно установить и включить. + +**Включён:** по умолчанию пользователи не могут запускать рабочие процессы. Включите настройку «Включён», чтобы разрешить использование рабочего процесса. + +**Параметры рабочего процесса (Workflow Parameters):** позволяет задать пользовательские параметры (только строки), которые будут показаны пользователю и заполнены им. Они передаются в рабочий процесс. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/index.mdx new file mode 100644 index 000000000000..e8c007b938c9 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/index.mdx @@ -0,0 +1,15 @@ +--- +sidebar_position: 4 +--- + +# Настройки + +Веб-интерфейс Dispatch — место, где собраны все возможности администрирования Dispatch; здесь живёт то, что, скорее всего, будет меняться часто \(параметры, которые меняют реже, находятся в файле конфигурации Dispatch\). + +Чтобы открыть настройки Dispatch, найдите пункт меню `Settings` и выберите проект, которым хотите управлять. + +<div style={{textAlign: 'center'}}> + +![настройки](/img/admin-ui-settings.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/definition.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/definition.mdx new file mode 100644 index 000000000000..ec6c3673549b --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/definition.mdx @@ -0,0 +1,5 @@ +# Определения + +Определения собирают и хранят толкования терминов из разных источников; благодаря этому участники инцидента понимают язык и термины, которые используются на протяжении инцидента. + +Одно определение может быть связано с одним или несколькими терминами \(если у термина несколько значений\). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/index.mdx new file mode 100644 index 000000000000..9f48fabbc5dd --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/index.mdx @@ -0,0 +1,3 @@ +# Знания + +Помимо оркестрации инцидентов, Dispatch умеет собирать базу знаний из данных по инцидентам. Ниже описаны доступные вам объекты и то, как вручную пополнять базу знаний об инцидентах. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/runbooks.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/runbooks.mdx new file mode 100644 index 000000000000..cdf47e58ee64 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/runbooks.mdx @@ -0,0 +1,36 @@ +# Инструкции (runbook) + +Инструкции (runbook) позволяют пользователям Dispatch динамически предоставлять участникам инцидента документы, которые могут пригодиться во время инцидента. + +Если шаблоны служат для описания состояния инцидента, то инструкции обычно описывают шаги по его разрешению. + +Насколько тесно связаны эти два понятия, зависит от инцидента и от того, как ваша организация ведёт инциденты. + +Сейчас есть два типа инструкций, хотя используются они одинаково. + +- Инцидент (Incident) +- Расследование (Investigation) + +### Вовлечение {#engagement} + +Документы-инструкции динамически подбираются к инциденту по их фильтру вовлечения. Как и для уведомлений, пользователь может задать, для каких инцидентов документ будет рекомендован участникам. + +При создании инцидента (или при изменении важного параметра инцидента, например типа) Dispatch отправит в канал инцидента уведомление с предложением документа. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-create-edit-runbook.png) + +</div> + +**Название (Name):** название документа. + +**Описание:** краткое описание документа. + +**Ссылка (Weblink):** гиперссылка на документ. + +**ID:** внешний идентификатор, по которому загружается документ. + +### Поддержание актуальности (Evergreen) {#evergreen} + +Если включить для инструкции режим evergreen, Dispatch будет отправлять владельцу инструкции напоминание по электронной почте с просьбой проверить, что инструкция актуальна. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/tag-type.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/tag-type.mdx new file mode 100644 index 000000000000..0b4fd156e22c --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/tag-type.mdx @@ -0,0 +1,15 @@ +# Типы тегов + +В Dispatch типы тегов позволяют группировать теги по категориям (например, «действующее лицо», «действие», «актив», «результат» и т. д.). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-knowledge-tag-types.png) + +</div> + +**Название (Name):** название типа тега. + +**Описание:** краткое описание типа тега. + +**Исключающий (Exclusive):** может ли у инцидента быть не больше одного тега этого типа. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/tag.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/tag.mdx new file mode 100644 index 000000000000..448f83242e37 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/tag.mdx @@ -0,0 +1,21 @@ +# Теги + +В Dispatch теги — это гибкие метаданные. Их можно вручную прикреплять к инцидентам или автоматически находить в данных инцидентов. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-knowledge-tags.png) + +</div> + +**Название (Name):** сама строка тега, то есть то, что вы ожидаете увидеть в данных инцидента. + +**Описание:** краткое описание тега (если нужно). + +**Тип (Type):** тип тега, который помогает отличать этот тег от других или относить его к категории. Типы тегов могут определять пользователи или плагины, синхронизирующие теги из внешних источников (например, названия приложений). + +**Источник:** откуда взялся тег. Для тегов, созданных через интерфейс, источник по умолчанию — Dispatch. + +**URI:** внешний локатор тега (если есть). + +**Обнаруживаемый (Discoverable):** Dispatch умеет обнаруживать теги автоматически: получив набор заранее определённых тегов, он просматривает все доступные ему данные инцидентов и с помощью NLP связывает эти данные с инцидентами (с текущим и задним числом). Если тег слишком общий (например, «the») и вы не хотите, чтобы он обнаруживался, этот флаг отключает автоматическое обнаружение для отдельного тега. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/term.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/term.mdx new file mode 100644 index 000000000000..be630d524477 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/knowledge/term.mdx @@ -0,0 +1,7 @@ +# Термины + +Термины — это слова и фразы, которые ничего не говорят стороннему наблюдателю, но имеют глубокий смысл внутри организации (например, аббревиатуры и названия). + +Возьмём для примера термин PCI. В мире безопасности эта аббревиатура обычно означает стандарт безопасности индустрии платёжных карт (Payment Card Industry). + +Любой определённый термин можно связать с командами, сервисами или людьми, чтобы они включались в инцидент. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/messaging.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/messaging.mdx new file mode 100644 index 000000000000..6a1490d481da --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/messaging.mdx @@ -0,0 +1,49 @@ +# Сообщения + +Dispatch умеет отправлять уведомления по электронной почте участникам — например, участникам инцидента. + +## Шаблоны уведомлений {#notification-templates} + +Шаблоны писем — [часть](https://github.com/helldweller/dispatch/tree/main/src/dispatch/messaging/email/templates) Dispatch: +это шаблоны [Jinja](https://jinja.palletsprojects.com/), которые во время работы компилируются в формат [MJML](https://mjml.io/). + +Эти шаблоны можно подстроить под себя. Если вы запускаете Dispatch через [Docker Compose](https://github.com/Jamyn/dispatch-docker/), +подключите том с каталогом изменённых шаблонов прямо в docker compose: + +``` + web: + image: dispatch-local + ... + volumes: + - "../dispatch-templates/messaging-email-templates:/usr/local/lib/python3.14/site-packages/dispatch/messaging/email/templates" +``` + +Такой подход позволяет изменить общий шаблон для _всех проектов_. + +Шаблоны можно также «подменять» _для отдельного проекта_. Создайте папку для проекта (по идентификатору проекта): + +``` +dispatch/messaging/email/templates/project_id/<project_id>/base.mjml +``` + +Если она есть, она будет использована в первую очередь, +иначе поиск шаблона спокойно откатится к шаблону по умолчанию: + +``` +dispatch/messaging/email/templates/base.mjml +``` + +## Markdown в уведомлениях {#markdown-in-the-notifications} + +:::warning +Помните о рисках безопасности, связанных с неэкранированным HTML: он может разойтись по всей системе. +::: + +По умолчанию текст уведомления — обычный текст, в котором спецсимволы и HTML экранированы. + +Однако синтаксис Markdown можно включить настройкой сервера: + +``` +DISPATCH_MARKDOWN_IN_INCIDENT_DESC=True +DISPATCH_ESCAPE_HTML=False +``` diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-atlassian-confluence.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-atlassian-confluence.mdx new file mode 100644 index 000000000000..ccf1b1a3d008 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-atlassian-confluence.mdx @@ -0,0 +1,73 @@ +--- +description: Страница настройки Atlassian Confluence. +--- + +# Настройка Atlassian Confluence + +:::info +Dispatch поставляется с плагинами хранилища и документов для Atlassian Confluence. На этой странице описаны доступные параметры этих плагинов. +::: + +## Параметры настройки Dispatch для плагина хранилища {#dispatch-configuration-variables-for-storage-plugin} + +### `API URL` \[обязательно\] {#api-url-required} + +> URL экземпляра Confluence. Для Cloud это корень сайта, например `https://your-site.atlassian.net/`; путь `/wiki` Dispatch добавляет сам, в том числе для сайта на собственном домене. Для Server/Data Center это URL экземпляра, включая context path, по которому он обслуживается, если такой есть. + +### `Hosting Type` \[по умолчанию: cloud\] {#hosting-type-default-cloud} + +> `cloud` или `server`. К Confluence Cloud Dispatch обращается через REST v2 API, а к Confluence Server/Data Center — через REST v1. Это разные API, поэтому значение должно соответствовать вашей установке. + +### `Username` \[обязательно\] {#username-required} + +> Имя пользователя для доступа к экземпляру Confluence. У этого пользователя должно быть право создавать страницы в пространстве. + +### `Password` \[обязательно\] {#password-required} + +> API-токен для доступа к экземпляру Confluence. Как создать новый API-токен, описано по [ссылке](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/). + +### `Root Incident Storage Page ID` \[обязательно\] {#root-incident-storage-page-id-required} + +> Идентификатор страницы, под которой создаётся собственная страница каждого инцидента. Его видно в URL страницы: `/pages/<id>/<title>`. +> +> Это **идентификатор страницы, а не ключ пространства**, и это должна быть именно страница, а не папка Confluence Cloud. Документ не может лежать в папке Confluence, поэтому иерархия хранилища Dispatch — это страницы под страницами: страница инцидента под этой, а его подстраницы — под ней. Пространство определяется по этой странице, так что больше настраивать нечего; каждый инцидент попадает в это пространство, если только проект не направит его в другое место через тип тега хранилища. +> +> Confluence требует, чтобы заголовки страниц в пространстве были уникальными, а Dispatch называет подпапки каждого инцидента по настройкам проекта `storage_folder_one`/`storage_folder_two` — одни и те же имена для всех инцидентов. Поэтому Dispatch добавляет к заголовку подстраницы префикс — заголовок страницы самого инцидента, и папка с именем `Logs` создаётся как `INC-0001 - Logs`. Имя, которое показывает Dispatch, при этом не меняется. +> +> :::warning +> В прежних выпусках здесь указывался ключ пространства, а рядом было отдельное поле `Parent ID of the pages`. При обновлении идентификатор родительской страницы переносится в это поле, а старое удаляется, так что существующий экземпляр править не нужно. Опасен ручной ввод: ключ пространства нельзя прочитать как страницу, поэтому хранилище инцидента не создаётся, а каждая попытка пишет в лог `Exception happened while creating page … under <space key>`. +> ::: + +### `Open On Close` \[по умолчанию: false\] {#open-on-close-default-false} + +> Управляет видимостью ресурсов при закрытии инцидента. Если включено, Dispatch сделает все ресурсы видимыми для всего рабочего пространства. +> +> :::note +> Плагин Confluence пока этого не реализует: настройка принимается, но ни на что не влияет. При закрытии инцидента попытка записывается в лог как событие о сбое. +> ::: + +### `Readonly` \[по умолчанию: false\] {#readonly-default-false} + +> При закрытии инцидента документ инцидента будет помечен как доступный только для чтения. Участники по-прежнему смогут работать с документом, а остальные читатели — нет. +> +> :::note +> Плагин Confluence пока этого не реализует — так же, как и `Open On Close` выше. +> ::: + +## Параметры настройки Dispatch для плагина документов {#dispatch-configuration-variables-for-document-plugin} + +### `API URL` \[обязательно\] {#api-url-required-1} + +> URL экземпляра Confluence. Для Cloud это корень сайта, например `https://your-site.atlassian.net/`; путь `/wiki` Dispatch добавляет сам, в том числе для сайта на собственном домене. Для Server/Data Center это URL экземпляра, включая context path, по которому он обслуживается, если такой есть. + +### `Hosting Type` \[по умолчанию: cloud\] {#hosting-type-default-cloud-1} + +> `cloud` или `server`. К Confluence Cloud Dispatch обращается через REST v2 API, а к Confluence Server/Data Center — через REST v1. Это разные API, поэтому значение должно соответствовать вашей установке. + +### `Username` \[обязательно\] {#username-required-1} + +> Имя пользователя для доступа к экземпляру Confluence. У этого пользователя должно быть право создавать страницы в пространстве. + +### `Password` \[обязательно\] {#password-required-1} + +> API-токен для доступа к экземпляру Confluence. Как создать новый API-токен, описано по [ссылке](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-duo.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-duo.mdx new file mode 100644 index 000000000000..7f0fcb4bbb73 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-duo.mdx @@ -0,0 +1,25 @@ +--- +description: Параметры настройки плагина Duo. +--- + +# Настройка Duo + +:::info +Dispatch из коробки поддерживает Duo для дополнительных проверок многофакторной аутентификации внутри приложения — например, при создании правила отсрочки. Для базовой функциональности этот плагин не обязателен. +::: + +## `Integration Key` \[Обязательный. Секрет: да\] {#integration-key-required-secret-true} + +> Ключ интеграции Auth API ('DI...'). + +## `Integration Secret Key` \[Обязательный. Секрет: да\] {#integration-secret-key-required-secret-true} + +> Секретный токен, используемый вместе с ключом интеграции. + +## `API Hostname` \[Обязательный\] {#api-hostname-required} + +> Имя хоста API ('api-....duosecurity.com') + +## Настройка Duo {#duo-setup} + +Войдите в Duo Admin Panel (панель администратора Duo) и откройте `Applications`. Нажмите `Protect an Application` и найдите в списке приложений запись Auth API. Нажмите `Protect` справа, чтобы настроить приложение и получить `integration key`, `secret key` и `API hostname`. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-g-suite.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-g-suite.mdx new file mode 100644 index 000000000000..78b72e882f8e --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-g-suite.mdx @@ -0,0 +1,107 @@ +--- +description: Страница настройки всех плагинов G Suite. +--- + +# Настройка интеграции с G Suite + +:::info +Dispatch поставляется с несколькими плагинами G Suite \(Docs, Groups, Drive и др.\). На этой странице описаны доступные параметры +этих плагинов и разрешения, которые нужны, чтобы их включить. +::: + +## Настройка Dispatch {#dispatch-configuration} + +Плагины G Suite настраиваются в веб-интерфейсе Dispatch в разделе «Настройки» -> «Проект» -> «Плагины» (Settings -> Project -> Plugins). Добавьте нужные плагины кнопкой `NEW`, затем откройте их настройки, нажав на три вертикальные точки. + +### Developer Key {#developer-key} + +> Используется службой Google API Discovery Service и защищает от ограничения частоты запросов. + +### Service Account Client Email {#service-account-client-email} + +> Значение `client_email` из файла конфигурации сервисного аккаунта Google Cloud Platform \(GCP\). + +### Service Account Client Id {#service-account-client-id} + +> Значение `client_id` из файла конфигурации сервисного аккаунта Google Cloud Platform \(GCP\). + +### Service Account Delegated Account {#service-account-delegated-account} + +> Аккаунт, которому делегируются права от сервисного аккаунта Google Cloud Platform \(GCP\). +> Исходящие письма и другие артефакты будут выглядеть отправленными от этого аккаунта. + +### Service Account Private Key {#service-account-private-key} + +> Значение `private_key` из файла конфигурации сервисного аккаунта Google Cloud Platform \(GCP\). + +### Service Account Private Key Id {#service-account-private-key-id} + +> Значение `private_key_id` из файла конфигурации сервисного аккаунта Google Cloud Platform \(GCP\). + +### Service Account Project Id {#service-account-project-id} + +> Значение `project_id` из файла конфигурации сервисного аккаунта Google Cloud Platform \(GCP\). + +### Google Workspace Domain {#google-workspace-domain} + +> Базовый домен, к которому относится этот сервисный аккаунт Google Cloud Platform \(GCP\). + +### Default Event Duration (Minutes) {#default-event-duration-minutes} + +> Длительность событий конференций по умолчанию в минутах. По умолчанию 1440 минут (1 день). + +## Настройка G Suite {#g-suite-setup} + +Чтобы настроить интеграцию с G Suite, создайте несколько ресурсов в Google Cloud Platform и привяжите их к своей +организации G Suite. + +## Включение необходимых API в Google Cloud Platform {#enable-required-apis-in-google-cloud-platform} + +Откройте [консоль](https://console.cloud.google.com/) Google Cloud Platform \(GCP\). Для интеграции с Dispatch +создайте новый проект GCP. + +Создайте новый сервисный аккаунт внутри проекта GCP \(APIs & Services > Credentials > Create Credentials > Service Account\). +Назначать этому сервисному аккаунту какие-либо разрешения Google Cloud, когда вас об этом спросят, не нужно. + +После создания скачайте ключ в формате JSON. Его значения понадобятся для настройки Dispatch: + +- `project_id` -> Service Account Project Id +- `private_key_id` -> Service Account Private Key Id +- `private_key` -> Service Account Private Key +- `client_email` -> Service Account Client Email +- `client_id` -> Service Account Client Id + +Затем создайте API-ключ разработчика \(APIs & Services > Credentials > Create Credentials > API Key\) и укажите его в поле Developer Key. + +Включите следующие API \(APIs and Services > Library\): + +- Google Drive API +- Google Drive Activity API +- Google People API +- Google Docs API +- Google Calendar API +- Gmail API +- Admin SDK \(нужен для создания групп и управления ими\) + +Наконец, создайте OAuth-приложение — через него G Suite будет авторизовать сервисный аккаунт и API-ключ \(APIs & Services > OAuth Consent Screen\). +Укажите следующие скоупы: + +```text +https://www.googleapis.com/auth/documents +https://www.googleapis.com/auth/drive +https://www.googleapis.com/auth/directory.readonly +https://www.googleapis.com/auth/drive.activity.readonly +https://mail.google.com/ +https://www.googleapis.com/auth/admin.directory.group +https://www.googleapis.com/auth/apps.groups.settings +https://www.googleapis.com/auth/calendar +``` + +**Примечание.** Если вы не собираетесь использовать Google Meet для конференций, скоуп `https://www.googleapis.com/auth/calendar` вам не нужен. + +## Подключение Dispatch к G Suite {#connecting-dispatch-to-g-suite} + +Откройте в админ-панели G Suite страницу [Domain-wide Delegation](https://admin.google.com/ac/owl/domainwidedelegation) +\(Security > API Controls > Domain-wide Delegation\) (делегирование на уровне домена) и добавьте нового API-клиента. + +Введите Client ID, который вы указали в поле Service Account Client Id, и вставьте список OAuth-скоупов, приведённых выше, через запятую. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-jira.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-jira.mdx new file mode 100644 index 000000000000..10a74663f647 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-jira.mdx @@ -0,0 +1,41 @@ +--- +description: Параметры настройки плагина Jira. +--- + +# Настройка Jira + +:::info +Dispatch из коробки поддерживает Jira. Каждая установка Jira уникальна, поэтому, скорее всего, вы захотите создать плагин Jira под свою организацию. Для базовой функциональности этот плагин не обязателен. Однако плагин типа `ticket` должен быть включён всегда. +::: + +## Конфигурация Dispatch {#dispatch-configuration} + +Плагин Jira настраивается в веб-интерфейсе Dispatch: «Настройки» -> «Проект» -> «Плагины». Добавьте плагин кнопкой `NEW` и затем отредактируйте его конфигурацию, нажав на три вертикальные точки. + +### Идентификатор или ключ проекта по умолчанию (Default Project Id or Key) {#default-project-id-or-key} + +> Задаёт проект Jira по умолчанию. Найти идентификатор проекта Jira можно [так](https://community.atlassian.com/t5/Jira-questions/JIRA-Project-ID/qaq-p/193094) или [так](https://confluence.atlassian.com/jirakb/how-to-get-project-id-from-the-jira-user-interface-827341414.html). + +### Имя типа задачи по умолчанию (Default Issue Type Name) {#default-issue-type-name} + +> Задаёт имя типа задачи Jira по умолчанию. + +### Тип размещения (Hosting Type) {#hosting-type} + +> Задаёт тип установки (`cloud` или `server`). По умолчанию `cloud`. + +### Имя пользователя (Username) {#username} + +> Имя пользователя для аутентификации в Jira API. + +### Пароль (Password) {#password} + +> Пароль для аутентификации в Jira API. + +### URL API (API URL) {#api-url} + +> Этот URL используется для обращения к Jira API. + +### URL для браузера (Browser URL) {#browser-url} + +> Этот URL используется для построения ссылок, открываемых в браузере. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-microsoft-teams.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-microsoft-teams.mdx new file mode 100644 index 000000000000..47b372483f33 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-microsoft-teams.mdx @@ -0,0 +1,114 @@ +--- +description: Параметры настройки плагина конференций Microsoft Teams. +--- + +# Настройка Microsoft Teams + +:::info +Плагин Microsoft Teams создаёт онлайн-встречу Teams, которая служит конференцией инцидента. Он аутентифицируется в Microsoft Graph по OAuth2 client-credentials flow и создаёт встречу от имени назначенного пользователя. Встречи Teams истекают через 60 дней после времени начала или окончания (срок продлевается ещё на 60 дней, если встречу обновили или активировали), так что ссылка для подключения остаётся рабочей всё время жизни инцидента независимо от настроенной длительности. +::: + +## Настройка Azure {#azure-setup} + +Плагин действует как приложение, а не как вошедший пользователь, поэтому ему нужна регистрация приложения с разрешением типа **application** и политика Teams, в которой назван пользователь, для которого создаются встречи. Нужны обе половины: действительный токен без политики возвращает `403`. + +### 1. Зарегистрируйте приложение {#1-register-an-application} + +В [центре администрирования Microsoft Entra](https://entra.microsoft.com) откройте **App registrations → New registration**. Запишите **Application (client) ID** и **Directory (tenant) ID**. + +### 2. Выдайте разрешение Graph {#2-grant-the-graph-permission} + +В разделе **API permissions** добавьте **Microsoft Graph → Application permissions → `OnlineMeetings.ReadWrite.All`**, затем нажмите **Grant admin consent**. + +:::caution +Это должно быть разрешение типа *application*. Делегированные разрешения относятся к вошедшему пользователю, и этот плагин их не использует. +::: + +### 3. Создайте секрет клиента {#3-create-a-client-secret} + +В разделе **Certificates & secrets → New client secret** скопируйте **значение** секрета (не его ID). Оно показывается только один раз. Секреты клиента истекают — поставьте напоминание: истёкший секрет проявляется как `invalid_client` в хронологии инцидента. + +### 4. Разрешите приложению создавать встречи для пользователя {#4-allow-the-application-to-create-meetings-for-a-user} + +Этот шаг легко пропустить. Выдайте приложению доступ к пользователю, в чьём календаре создаются встречи: + +```powershell +Import-Module MicrosoftTeams +Connect-MicrosoftTeams + +New-CsApplicationAccessPolicy -Identity Dispatch-Conference ` + -AppIds "<application-client-id>" -Description "Dispatch conference plugin" + +Grant-CsApplicationAccessPolicy -PolicyName Dispatch-Conference ` + -Identity "<user-object-id>" +``` + +Назначение политики может вступать в силу до 30 минут. См. [Разрешение приложениям доступа к онлайн-встречам от имени пользователя](https://learn.microsoft.com/en-us/graph/cloud-communication-online-meeting-application-access-policy). + +## Конфигурация Dispatch {#dispatch-configuration} + +Плагин Microsoft Teams настраивается в веб-интерфейсе Dispatch: «Настройки» -> «Проект» -> «Плагины». Добавьте плагин кнопкой `NEW` и затем отредактируйте его конфигурацию, нажав на три вертикальные точки. + +### URL центра авторизации (MS team Authority URL) {#ms-team-authority-url} + +> `https://login.microsoftonline.com/<directory-tenant-id>`. Укажите конкретный тенант: `common` и `organizations` для client-credentials flow не поддерживаются. + +### Идентификатор клиента (client id) {#client-id} + +> Application (client) ID из шага 1. + +### Секрет клиента Azure (Azure Client Secret) {#azure-client-secret} + +> Значение секрета клиента из шага 3. + +### Идентификатор пользователя (User id) {#user-id} + +> **Object ID** пользователя, от имени которого приложение создаёт встречи, — не его адрес эл. почты. Это должен быть тот же пользователь, что указан в политике доступа приложения на шаге 4. + +### Разрешить автоматическую запись (Allow Auto Recording) {#allow-auto-recording} + +> Включите, если хотите записывать встречи по умолчанию. По умолчанию выключено. + +### Длительность встречи по умолчанию, в минутах (Default Meeting Duration (Minutes)) {#default-meeting-duration-minutes} + +> Длительность конференций по умолчанию в минутах. По умолчанию 1440 минут (1 день). К встречам Teams можно подключаться и после запланированного окончания, так что этот параметр в основном определяет, когда встреча истечёт, а не обрывает конференцию. + +### Требовать код доступа к встрече (Require a Meeting Passcode) {#require-a-meeting-passcode} + +> Требовать код доступа при подключении по идентификатору встречи. По умолчанию включено. +> +> Код доступа действует **только** при подключении по идентификатору встречи. Ссылка для подключения несёт собственный контекст аутентификации встречи, поэтому у тех, кто переходит по ссылке из Slack, код никогда не запрашивается: включение этого параметра не усложняет обычный путь. Для звонков по телефону используется отдельный идентификатор конференции (`audioConferencing.conferenceId`), на который этот параметр не влияет. +> +> Поскольку код доступа бесполезен без идентификатора встречи, с которым он связан, Dispatch публикует их вместе: описание конференции выглядит как `Password: aB3dEf7h (meeting ID 123 456 789)`. + +## Диагностика {#troubleshooting} + +Сбои записываются в хронологию инцидента вместе с причиной, которую вернул Graph. + +| Симптом | Причина | +| --- | --- | +| `invalid_client` | Неверный или истёкший секрет клиента. | +| `403` при действительном токене | Для настроенного пользователя нет политики доступа приложения, либо она ещё не применилась. | +| `404` при создании | **Идентификатор пользователя (User id)** — не object ID, или такого пользователя нет в тенанте. | +| `429` | Graph ограничивает приложение. Сообщение содержит значение `Retry-After` как есть (Graph присылает либо число секунд, либо HTTP-дату). Dispatch не повторяет запрос: повтор на записывающей конечной точке рискует создать вторую конференцию для одного инцидента. | + +## Ограничения {#limits} + +Microsoft документирует лимит в **2000 встреч на пользователя в месяц** для сведений о встречах. Поскольку Dispatch создаёт все конференции под единственным пользователем, настроенным выше, именно в этот потолок плагин упрётся первым. Microsoft не публикует лимит запросов в секунду для `/onlineMeetings` в таблице ограничений по сервисам; если приложение ограничено, Graph отвечает `429` с `Retry-After`, и Dispatch выводит и то и другое в хронологию инцидента. + +## Примечания {#notes} + +- `add_participant` и `remove_participant` держат список участников встречи в соответствии с участниками инцидента. Это **метаданные о составе, а не контроль доступа**: ссылка для подключения работает для любого, у кого она есть, так что добавление не даёт ничего сверх того, что уже даёт опубликованная ссылка, а удаление не выгоняет участника из идущей встречи и не отзывает ссылку. Участники добавляются с ролью `attendee`: Microsoft не позволяет назначать `presenter` или `coorganizer` учётным записям, которые Entra не может разрешить, а среди реагирующих могут быть внешние люди. +- При каждом обновлении Graph заменяет весь список участников, поэтому Dispatch перед каждым изменением читает встречу и отправляет существующих участников без изменений. Сбой записывается в хронологию инцидента и не прерывает добавление или удаление участника во всех остальных местах. +- Допуск из лобби и права докладчика — отдельная тема, которой этот плагин не управляет. +- **Не проверено на живом тенанте.** Участники идентифицируются только по user principal name; Graph описывает более полный объект `identity` как необязательный, а чтобы его разрешить, помимо перечисленных выше разрешений понадобился бы `User.Read.All`. Есть также сообщения, что Graph отвечает `200` на обновление списка участников с разрешениями приложения, не применяя его. Поскольку сбой состава никогда не прерывает инцидент, установка, где это молча ничего не делает, выглядит так же, как та, где всё работает. Прежде чем полагаться на точность состава, прогоните на своём тенанте живой набор тестов, включаемый вручную (`tests/plugins/dispatch_microsoft_teams/test_teams_live.py` с заданной `DISPATCH_MSTEAMS_TEST_ATTENDEE_UPN`). +- Сейчас в Dispatch ничто не вызывает `delete` для конференции; метод реализован для единообразия интерфейса. +- Встреча создаётся с начальным составом участников: реагирующие, определённые для инцидента, минус те, кто выключил у себя в настройках **«Автоматически подключать меня к конференциям инцидентов» (Add me automatically to incident bridges)**. Тот же список, та же роль `attendee` и те же оговорки, что и для `add_participant` выше, — только состав задаётся одним запросом, а не добавляется потом, поэтому состав, который Graph отвергнет, провалит создание, а не оставит встречу, о которой Dispatch ничего не знает. Инцидент без таких реагирующих получает встречу без участников, и это не ошибка. +- `description` плагин принимает, но не использует: у `onlineMeeting` нет поля повестки. + +## Обновление {#upgrading} + +До исправлений из [Jamyn/dispatch#81](https://github.com/Jamyn/dispatch/issues/81) этот плагин вообще не мог аутентифицироваться: он передавал строку там, где MSAL требует список скоупов, поэтому каждая попытка падала, не доходя до Graph, и ошибка проглатывалась. Значит, ни одна существующая установка конференций не создавала, и прежнего рабочего поведения, которое нужно сохранять, нет. Тем не менее две вещи отличаются от того, что старый код *пытался* сделать: + +- Темой встречи теперь служит **название** инцидента (а если его нет — `Situation Room for <incident name>`), как в плагине Zoom. Раньше это было кодовое имя инцидента. Названия инцидентов описательнее кодовых имён, а тема видна всем в тенанте, у кого есть доступ к календарю настроенного пользователя. +- Код доступа запрашивается по умолчанию. См. **Требовать код доступа к встрече (Require a Meeting Passcode)** выше; выключите параметр, чтобы вернуть прежний замысел. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-opsgenie.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-opsgenie.mdx new file mode 100644 index 000000000000..17576fba7743 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-opsgenie.mdx @@ -0,0 +1,17 @@ +--- +description: Параметры настройки плагина Opsgenie. +--- + +# Настройка Opsgenie + +:::info +Dispatch поставляется с поддержкой определения дежурных по расписаниям через API Opsgenie. Ниже описано, как настроить плагин Opsgenie для работы с `Dispatch.` +::: + +## Настройка Dispatch {#dispatch-configuration} + +Плагин Opsgenie настраивается в веб-интерфейсе Dispatch в разделе «Настройки» -> «Проект» -> «Плагины» (Settings -> Project -> Plugins). Добавьте плагин кнопкой `NEW`, затем откройте его настройки, нажав на три вертикальные точки. + +### API Key {#api-key} + +> Ключ для обращения к API Opsgenie. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-pagerduty.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-pagerduty.mdx new file mode 100644 index 000000000000..110dcbedee7a --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-pagerduty.mdx @@ -0,0 +1,35 @@ +--- +description: Параметры настройки плагина PagerDuty. +--- + +# Настройка PagerDuty + +:::info +Dispatch поставляется с поддержкой определения дежурных по расписаниям через API PagerDuty. +::: + +### Настройка Dispatch {#dispatch-configuration} + +Плагин PagerDuty настраивается в веб-интерфейсе Dispatch в разделе «Настройки» -> «Проект» -> «Плагины» (Settings -> Project -> Plugins). Добавьте плагин кнопкой `NEW`, затем откройте его настройки, нажав на три вертикальные точки. + +#### API Key {#api-key} + +> Ключ для обращения к API PagerDuty. См.: https://support.pagerduty.com/docs/generating-api-keys + +#### From Email {#from-email} + +> Адрес, который подставляется в поле «From» при любом вызове дежурного. + +#### Instance API URL {#instance-api-url} + +> URL вашего API (по умолчанию `https://api.pagerduty.com`, то есть экземпляр в США). + +## Настройка дежурной службы {#oncall-service-configuration} + +Откройте /services на веб-сервере с Dispatch и добавьте новую службу. Выберите тип `pagerduty-oncall` и укажите Service ID из PagerDuty в поле «Внешний идентификатор» (External Id). + +<div style={{textAlign: 'center'}}> + +![](/img/pagerduty-service-setup.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-slack.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-slack.mdx new file mode 100644 index 000000000000..7085ce292ed7 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-slack.mdx @@ -0,0 +1,236 @@ +--- +description: Параметры настройки плагина Slack. +--- + +# Настройка Slack + +Dispatch из коробки поддерживает Slack. Ниже описано, как настроить плагин Slack для работы с `Dispatch`. + +## Events Mode или Socket Mode {#events-mode-vs-socket-mode} + +Dispatch поддерживает и [Events Mode](https://api.slack.com/events-api) (режим событий), и [Socket Mode](https://api.slack.com/apis/connections/socket) (режим сокетов). + +Какой режим выбрать? + +- Если Dispatch будет слушать публичный статический HTTP-адрес, рекомендуем **Events Mode**. +- Если Dispatch разворачивается за корпоративным файрволом или у вас есть опасения по безопасности, рекомендуем **Socket Mode**. + +Подробнее о переменных — в разделе [Конфигурация Dispatch](#dispatch-configuration) ниже. + +### Events Mode {#events-mode} + +Для Events Mode нужны конкретные URL-адреса, доступные **публично**: + +- `Dispatch` принимает общие события на конечной точке `/api/v1/<organization>/events/slack/event` (например, участник вошёл в канал, реакции). +- `Dispatch` принимает события команд на конечной точке `/api/v1/<organization>/events/slack/command` (команды `/dispatch-*`). +- `Dispatch` принимает события действий на конечной точке `/api/v1/<organization>/events/slack/action` (диалоги и модальные окна). + +### Socket Mode {#socket-mode} + +Чтобы включить Socket Mode, добавьте токен приложения для Socket Mode в поле `Socket Mode App Token` плагинов `Slack Plugin - Conversation Management` и `Slack Plugin - Contact Information Resolver` в веб-интерфейсе Dispatch: «Настройки» -> «Проект» -> «Плагины». + +Socket Mode не требует настройки конечных точек: в этом режиме их значения игнорируются. + +Для Socket Mode нужен отдельный процесс (помимо основного веб-сервера Dispatch), который будет принимать события по WebSocket. + +Проще всего запустить его такой командой CLI: + +``` +dispatch server slack <organization> <project> +``` + +Этот процесс нужно запускать как демон, так же как и веб-сервер Dispatch. + +## Конфигурация Slack {#slack-configuration} + +Для вашего приложения Slack в [веб-интерфейсе Slack API](https://api.slack.com/apps) нужно задать следующие параметры — и для `events mode`, и для `socket mode`. + +### Event Subscriptions (подписки на события) {#event-subscriptions} + +Чтобы Dispatch мог обрабатывать события Slack, в разделе `Events Subscriptions` убедитесь, что `Request URL` указывает на конечную точку подписки на события сервера Dispatch: `/api/v1/<organization>/events/slack/event`. Замените `<organization>` на имя вашей организации. По умолчанию это `default`. + +Затем в разделе `Subscribe to bot events` добавьте следующие события бота: + +| Событие | Описание | +| --------------------- | -------------------------------------------------- | +| member_joined_channel | Пользователь вошёл в публичный или приватный канал | +| member_left_channel | Пользователь покинул публичный или приватный канал | +| message.groups | В приватный канал отправлено сообщение | + +### Interactivity (интерактивность) {#interactivity} + +Чтобы Dispatch мог создавать интерактивные элементы — диалоги и модальные окна, — убедитесь, что `Request URL` указывает на конечную точку действий сервера Dispatch: `/api/v1/<organization>/events/slack/action`. Замените `<organization>` на имя вашей организации. По умолчанию это `default`. + +### Select Menus (меню выбора) {#select-menus} + +На той же странице `Interactivity & Shortcuts`, в разделе `Select Menus`, задайте `Options Load URL` равным `/api/v1/<organization>/events/slack/menu`. Замените `<organization>` на имя вашей организации. По умолчанию это `default`. + +Это отдельное поле, не связанное с `Request URL` выше, и значение оттуда оно не наследует. Dispatch использует его для меню с подсказками, которые подгружают варианты по запросу, а не встраивают их в модальное окно: выбор тегов и выбор проекта в установках, где включено больше 100 проектов. Если поле не задано, такие меню открываются пустыми и остаются пустыми, а поскольку поле обязательное, форму нельзя отправить. + +### Slash Commands (слеш-команды) {#slash-commands} + +Чтобы слеш-команды Dispatch заработали, сначала добавьте их в приложение Slack. Убедитесь, что поле `Command` в веб-интерфейсе Slack API совпадает с именем команды в плагине Slack в веб-интерфейсе Dispatch, а `Request URL` указывает на конечную точку команд сервера Dispatch: `/api/v1/<organization>/events/slack/command`. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-setup-commands-0.png) + +</div> + +<div style={{textAlign: 'center'}}> + +![](/img/slack-setup-commands-1.png) + +</div> + +<div style={{textAlign: 'center'}}> + +![](/img/slack-setup-commands-2.png) + +</div> + +### OAuth & Permissions (OAuth и разрешения) {#oauth--permissions} + +`Bot User OAuth Access Token` используется для запросов к Slack API. + +#### Скоупы {#scopes} + +Ниже перечислены скоупы бота и пользователя, которые нужны приложению Dispatch для Slack, чтобы работать корректно. + +**Bot Token Scopes** + +```text +bookmarks:write +channels:read +chat:write +commands +files:read +groups:history +groups:read +groups:write +im:history +im:read +im:write +mpim:history +mpim:read +mpim:write +pins:write +reactions:read +reactions:write +team:read +users:read +users:read.email +users.profile:read +users:write +``` + +**User Token Scopes** + +```text +channels:read +groups:history +groups:read +``` + +## Конфигурация Dispatch {#dispatch-configuration} + +Плагины Slack для Dispatch — управление каналами обсуждения и поиск контактной информации — настраиваются в веб-интерфейсе Dispatch: «Настройки» -> «Проект» -> «Плагины». Добавьте нужные плагины кнопкой `NEW` и затем отредактируйте их конфигурацию, нажав на три вертикальные точки. + +### Плагин каналов обсуждения (Conversation Management) {#conversation-management-plugin} + +#### Токен бота (API Bot Token) {#api-bot-token} + +> Токен бота приложения Slack, нужный для обращения к Slack API. В Slack он называется «Bot User OAuth Access Token» и показывается соавторам приложения при его установке. + +#### Токен приложения для Socket Mode (Socket Mode App Token) {#socket-mode-app-token} + +> Токен приложения Slack для Socket Mode; выдаётся при включении Socket Mode и служит для аутентификации в WebSocket API. Если Socket Mode не используется, значение игнорируется. + +#### Секрет подписи (Signing Secret) {#signing-secret} + +> Секрет для проверки подписей, которыми Slack снабжает каждый HTTP-запрос. В Slack он называется «Signing Secret». + +#### Идентификатор пользователя приложения (App User Id) {#app-user-id} + +> Идентификатор бот-пользователя приложения Slack: по нему Dispatch отфильтровывает события, порождённые самим приложением \(например, сообщение, опубликованное в канале\). Получить идентификатор бот-пользователя \(`UXXXXXXXX`\) можно через конечную точку [auth.test](https://api.slack.com/methods/auth.test/test), передав токен бота приложения \(`xoxb-*`\)." + +#### Приватные каналы (Private Channels) {#private-channels} + +> Создавать ли для инцидентов приватные каналы Slack вместо публичных. + +#### Запрет тредов (Ban Threads) {#ban-threads} + +> Разрешать или запрещать треды (ответы в ветках) в каналах инцидентов. + +#### Реакция для события хронологии (Timeline Event Reaction) {#timeline-event-reaction} + +> Реакция, по которой сообщение из канала инцидента добавляется в хронологию инцидента. + +#### Строки команд (Command Strings) {#command-strings} + +> Имена слеш-команд, которые будет предоставлять ваше приложение Slack. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-plugin-conversation-management.png) + +</div> + +При желании их значения можно переопределить. Ниже приведены описания команд — их удобно скопировать в настройки слеш-команд вашего приложения Slack. + +| Команда | Описание | +| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `/dispatch-add-timeline-event` | Открывает модальное окно для добавления события в хронологию инцидента. | +| `/dispatch-assign-role` | Открывает модальное окно для назначения роли участнику. | +| `/dispatch-engage-oncall` | Открывает модальное окно для вовлечения дежурного. | +| `/dispatch-list-incidents [project name]` | Показывает активные и стабильные инциденты, а также закрытые за последние 24 часа — по одному проекту или по всем сразу. | +| `/dispatch-list-my-tasks` | Открывает модальное окно со списком ваших открытых и решённых задач по инциденту. | +| `/dispatch-list-participants` | Открывает модальное окно со списком участников инцидента. | +| `/dispatch-list-signals` | Открывает модальное окно со списком определений сигналов, настроенных для канала обсуждения, из которого запущена команда. | +| `/dispatch-list-tasks` | Открывает модальное окно со списком открытых и решённых задач инцидента. | +| `/dispatch-list-workflows` | Показывает рабочие процессы, запускавшиеся в ходе этого инцидента. | +| `/dispatch-report-executive` | Открывает модальное окно для составления отчёта для руководства. | +| `/dispatch-report-incident` | Открывает модальное окно для сообщения об инциденте. Команду можно запускать из каналов, не связанных с инцидентом, если в них состоит бот Dispatch. | +| `/dispatch-report-tactical` | Открывает модальное окно для составления тактического отчёта. | +| `/dispatch-run-workflow` | Запускает рабочий процесс и привязывает его артефакты к этому инциденту. | +| `/dispatch-update-incident` | Открывает модальное окно для обновления инцидента. | +| `/dispatch-notifications-group` | Открывает модальное окно для редактирования группы уведомлений. | +| `/dispatch-update-participant` | Открывает модальное окно для обновления данных участника. | +| `/dispatch-create-task` | Открывает модальное окно для создания задачи по инциденту. | +| `/dispatch-create-case` | Открывает модальное окно для создания кейса. | +| `/dispatch-update-case` | Открывает модальное окно для обновления кейса. Запускается из канала кейса. | +| `/dispatch-escalate-case` | Открывает модальное окно для эскалации кейса в инцидент. Запускается из канала кейса. | +| `/dispatch-engage-user` | Открывает модальное окно, чтобы попросить участника кейса подтвердить личность через MFA. Запускается из канала кейса. | +| `/dispatch-summary` | Если это разрешено для данного типа кейса/инцидента, создаёт вводную сводку, сгенерированную ИИ. | + +### Плагин контактов (Contact Information Resolver) {#contact-information-resolver-plugin} + +#### Токен бота (API Bot Token) {#api-bot-token-1} + +> Токен бота приложения Slack, нужный для обращения к Slack API. В Slack он называется «Bot User OAuth Access Token» и показывается соавторам приложения при его установке. + +#### Токен приложения для Socket Mode (Socket Mode App Token) {#socket-mode-app-token-1} + +> Токен приложения Slack для Socket Mode; выдаётся при включении Socket Mode и служит для аутентификации в WebSocket API. Если Socket Mode не используется, значение игнорируется. + +#### Секрет подписи (Signing Secret) {#signing-secret-1} + +> Секрет для проверки подписей, которыми Slack снабжает каждый HTTP-запрос. В Slack он называется «Signing Secret». + +#### Идентификатор поля профиля «Отдел» (Profile Department Field Id) {#profile-department-field-id} + +> Идентификатор поля профиля, в котором хранится отдел (Department). + +#### Идентификатор поля профиля «Команда» (Profile Team Field Id) {#profile-team-field-id} + +> Идентификатор поля профиля, в котором хранится команда (Team). + +#### Идентификатор поля профиля «Веб-ссылка» (Profile Weblink Field Id) {#profile-weblink-field-id} + +> Идентификатор поля профиля, в котором хранится веб-ссылка. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-plugin-contact-information-resolver.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-zoom.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-zoom.mdx new file mode 100644 index 000000000000..31b7103d3d68 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/configuring-zoom.mdx @@ -0,0 +1,94 @@ +--- +description: Параметры настройки плагина Zoom. +--- + +# Настройка Zoom + +:::info +Dispatch поставляется с поддержкой конференций Zoom. Плагин Zoom создаёт конференцию длительностью до 24 часов (максимум, который допускает Zoom) и генерирует пароль для её защиты. Ссылка, которую плагин возвращает в мессенджер, устроена так, что достаточно по ней перейти — вводить пароль не нужно. +::: + +:::caution Обновление со старой версии Dispatch +Раньше этот плагин проходил аутентификацию через JWT-приложение Zoom — такой способ Zoom отключил 01.09.2023. Теперь плагин использует **Server-to-Server OAuth**, а старых полей **API Key** и **API Secret** больше нет. + +Поэтому уже существующий экземпляр плагина Zoom хранит конфигурацию, которую эта версия прочитать не может, а нечитаемую конфигурацию плагина Dispatch считает отсутствующей и ошибку не выбрасывает. Плагин по-прежнему выглядит включённым, но вместо конференции каждый инцидент получает в хронологию запись *"The Zoom plugin configuration could not be read…"*. Старые JWT-ключ и секрет сконвертировать нельзя, да и для Zoom они в любом случае уже бесполезны. + +Чтобы восстановить работу: + +1. Создайте приложение Server-to-Server OAuth и настройте плагин, как описано ниже, — **отдельно для каждого проекта в каждой организации**. Экземпляры плагинов привязаны к проектам, поэтому установке с пятью проектами в двух организациях понадобится десять экземпляров. +2. Заполните заново **все** поля, включая **Zoom API User Id**. Сохранённую конфигурацию разобрать невозможно, поэтому форма редактирования откроется пустой — даже для полей, которые не менялись. +3. Удалите или деактивируйте старое JWT-приложение в Marketplace, если оно ещё существует. +::: + +:::warning Повторное открытие формы плагина стирает client secret +Dispatch возвращает сохранённый client secret в интерфейс замаскированным — как `**********`, а при сохранении форма записывает обратно то, что в ней лежит. Если открыть плагин Zoom, чтобы поменять любое другое поле — скажем, API User Id, — и сохранить, client secret будет перезаписан этими звёздочками, и аутентификация начнёт падать с ошибкой `Invalid client_id or client_secret`. **Вводите Client Secret заново при каждом сохранении этой формы.** Это касается любого плагина с секретным полем, не только Zoom. +::: + +## Создание приложения Zoom {#creating-the-zoom-app} + +1. В [Zoom App Marketplace](https://marketplace.zoom.us/) войдите как администратор аккаунта и выберите **Develop → Build App → Server-to-Server OAuth**. (Приложение типа JWT, которое раньше требовалось этому плагину, создать уже нельзя.) +2. Дайте приложению имя, заполните обязательные основные сведения и активируйте его. +3. В разделе **Scopes** добавьте скоупы для всех четырёх операций, которые выполняет плагин: создание, чтение, обновление и удаление встречи. + + Zoom предлагает два семейства скоупов, и какое из них вы увидите, зависит от приложения. Новым приложениям, как правило, доступны только **гранулярные** (granular) скоупы, а классические названия могут быть недоступны: + + | Операция | Классические | Гранулярные | + | --- | --- | --- | + | Создать встречу | `meeting:write:admin` | `meeting:write:meeting:admin` | + | Прочитать встречу | `meeting:read:admin` | `meeting:read:meeting:admin` | + | Обновить список приглашённых | `meeting:write:admin` | `meeting:update:meeting:admin` | + | Удалить встречу | `meeting:write:admin` | `meeting:delete:meeting:admin` | + + Гранулярные скоупы делят то, что покрывал классический `meeting:write:admin`, на три части. Типичная ошибка — выбрать только гранулярную пару на чтение и запись: встречи создаются успешно, а затем каждое обновление списка приглашённых и удаление заканчиваются ошибкой. + + Об отсутствующем скоупе при выдаче токена никто не сообщит: токен выдаётся, а вызов API после этого падает, поэтому добавьте скоупы до настройки Dispatch. +4. На странице **App Credentials** скопируйте **Account ID**, **Client ID** и **Client Secret**. + +## Настройка Dispatch {#dispatch-configuration} + +Плагин Zoom настраивается в веб-интерфейсе Dispatch в разделе «Настройки» -> «Проект» -> «Плагины» (Settings -> Project -> Plugins). Добавьте плагин кнопкой `NEW`, затем откройте его настройки, нажав на три вертикальные точки. + +Вводите учётные данные только через эту форму. Не передавайте их в командной строке и не вставляйте в URL: Dispatch хранит client secret в зашифрованной колонке, а любой из этих способов выдаст его в историю оболочки, список процессов или логи прокси. + +### Zoom API User Id {#zoom-api-user-id} + +> Email или идентификатор пользователя, от имени которого создаются встречи. + +### Account ID {#account-id} + +> Account ID приложения Server-to-Server OAuth со страницы App Credentials. + +### Client ID {#client-id} + +> Client ID приложения Server-to-Server OAuth. + +### Client Secret {#client-secret} + +> Client secret приложения Server-to-Server OAuth. **Обращайтесь с ним как с учётными данными**: любой, у кого он есть, может действовать от имени аккаунта в пределах скоупов приложения. Если он когда-нибудь утечёт, перевыпустите его в Marketplace. + +### Default Meeting Duration (Minutes) {#default-meeting-duration-minutes} + +> Длительность конференций по умолчанию в минутах. По умолчанию 1440 минут (1 день). + +## Проверка настройки {#validating-the-configuration} + +Создайте тестовый инцидент в проекте с включённым плагином и убедитесь, что появилась ссылка на конференцию. Любой сбой — при аутентификации или в самом вызове создания встречи — записывается в хронологию инцидента вместе с причиной, которую назвал Zoom, а конференция к инциденту не прикрепляется. + +| Симптом | Причина | +| --- | --- | +| `HTTP 400: Invalid client_id or client_secret` | Неверный Client ID или Client Secret, либо приложение деактивировано. Обратите внимание: эндпоинт токена Zoom отвечает `400`, а не `401`. | +| `HTTP 400: Invalid account_id` (или 400 с упоминанием аккаунта) | Account ID не соответствует аккаунту приложения. | +| `HTTP 400: grant type … is not supported` | В запросе токена использован grant, который Zoom здесь не принимает. Server-to-Server OAuth использует `account_credentials`. | +| `Zoom creation of the meeting failed with HTTP 400` и сообщение с названием скоупа | У приложения не хватает нужного скоупа — чаще всего скоупа на обновление или удаление из гранулярного семейства. | +| `This API does not support client credentials for authorization` | Ответ пришёл от API, а не от эндпоинта токена: токен `client_credentials` предъявлен эндпоинту, которому нужна авторизация аккаунта. | +| `The Zoom plugin configuration could not be read` | Плагин всё ещё хранит упразднённые API Key / API Secret. См. примечание об обновлении выше. | + +## Примечания {#notes} + +- Токены доступа живут один час, а refresh-токен Zoom не выдаёт. Dispatch получает токен на каждую операцию и использует его повторно для всех вызовов внутри этой операции; на диск токены не записываются. Ротировать по расписанию ничего не нужно, кроме самого client secret — с той периодичностью, которую требует ваша политика. +- Zoom ограничивает создание встреч **100 в день** для настроенного API-пользователя, а обновления встречи — **100 в день на одну встречу**. Первый лимит определяет, сколько конференций установка может открыть за 24 часа на весь аккаунт; второй — сколько раз можно менять список приглашённых у одного долгого инцидента. Оба проявляются как ошибки в хронологии, а не как молчаливые сбои. +- `add_participant` и `remove_participant` держат список `meeting_invitees` встречи в соответствии с участниками инцидента. Это **метаданные списка приглашённых, а не управление доступом**: ссылка для подключения работает у любого, у кого она есть, поэтому добавление в список не даёт ничего сверх опубликованной ссылки, а удаление из него никого не выгоняет и ссылку не отзывает. Поведение зала ожидания — отдельный вопрос, которым этот плагин не управляет. +- Zoom заменяет список приглашённых целиком, поэтому перед каждым изменением Dispatch читает встречу и отправляет существующих приглашённых заново. Сбой записывается в хронологию инцидента и не мешает добавлению или удалению участника во всех остальных местах. +- При чтении Zoom действительно возвращает список приглашённых — это проверено на реальном аккаунте, что и закрыло [issue #129](https://github.com/Jamyn/dispatch/issues/129), — поэтому список ведётся как обычно: если при создании добавить двух участников реагирования (responders), а затем третьего, при чтении вернутся все трое. **Если чтение когда-нибудь вернётся без списка приглашённых, Dispatch оставит список как есть и обновлять его не станет**: пересобирать список, который заменяется целиком, из ответа, в котором ничего нет, значило бы выкинуть всех, кто уже был в нём. Это пишется в лог, а не в хронологию инцидента — это не сбой, а первые участники реагирования и так уже в списке. Такого случаться не должно; если всё же случилось, строка лога показывает, в каком виде ответил Zoom, и об этом стоит сообщить. Возможность подключиться ни у кого при этом не меняется. +- Встреча создаётся сразу с начальным списком приглашённых: это участники реагирования, определённые для инцидента, за вычетом тех, кто выключил в своих настройках **«Автоматически подключать меня к конференциям инцидентов»** (Add me automatically to incident bridges). Список отправляется внутри запроса на создание, а не добавляется потом, поэтому, если Zoom отклонит список, создание завершится ошибкой — а не оставит встречу, о которой Dispatch ничего не знает. Инцидент без таких участников получает встречу без приглашённых, и это не ошибка; запрос, который получает Zoom, в этом случае ровно тот же, каким он был до появления этого списка. +- Поддержка Zoom заявляла на форуме разработчиков, что `meeting_invitees` используется только их календарными интеграциями, поэтому приглашённый — добавленный при создании или позже — может так и не появиться в клиенте Zoom. Dispatch отправляет то, что описано в документации API. Сотрудники Zoom также заявляли, что заполнение этого списка **не** порождает писем, так что ни создание конференции, ни обновление её списка приглашённых никого не уведомляет. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/index.mdx new file mode 100644 index 000000000000..b3370ea3b3d2 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/plugins/index.mdx @@ -0,0 +1,15 @@ +# Плагины + +Прежде чем настраивать и использовать плагины, прочитайте в документации по [CLI](../cli#plugins), как их устанавливать. + +Большая часть возможностей Dispatch приходит из плагинов. Сейчас веб-интерфейс Dispatch умеет только включать и выключать плагины для каждого проекта. Чтобы изменить поведение плагинов или их конфигурацию, правки нужно выкатывать через файл конфигурации сервера. Подробнее — в документации по конфигурации [сервера](server). + +По умолчанию ни один плагин не _обязателен_ для создания инцидента. Каждый включённый плагин добавляет свой шаг к процессу работы с инцидентом (например, создание каналов Slack, документов Google и т. п.). + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-plugins.png) + +</div> + +Хотите добавить в Dispatch свою функциональность через плагины? См. документацию по [участию в разработке](../contributing/plugins). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/project.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/project.mdx new file mode 100644 index 000000000000..914d319b52f2 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/project.mdx @@ -0,0 +1,36 @@ +--- +description: Обзор проектов Dispatch. +sidebar_position: 0 +--- + +# Проекты + +Каждый кейс или инцидент в Dispatch привязан к проекту. Конфигурация проекта определяет, как создаются и ведутся кейсы и инциденты. Благодаря этому разные команды могут использовать Dispatch по-разному. + +От собственных типов и приоритетов кейсов или инцидентов до отдельного представления метрик команды. + +### Когда создавать новый проект, а когда использовать существующий? {#when-should-i-create-a-new-project-vs-using-an-existing-one} + +Как правило, новый проект стоит создавать, когда команды почти не пересекаются в работе над кейсами или инцидентами. + +Например, можно создать проект `security` для всех кейсов и инцидентов, связанных с безопасностью, и проект `reliability` для всех инцидентов, связанных с отказами. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-project.png) + +</div> + +**Название (Name):** название вашего проекта. + +**Описание (Description):** описание вашего проекта. + +**Цвет (Color):** цвет проекта, чтобы визуально отличать его от других проектов. + +**Годовая стоимость сотрудника (Annual Employee Cost):** средняя годовая стоимость одного сотрудника. + +**Рабочих часов в году (Business Year Hours):** число рабочих часов в году. Используется для расчёта почасовой ставки. + +**Email владельца (Owner Email):** почтовый адрес владельца проекта. + +**Канал обсуждения владельца (Owner Conversation):** канал обсуждения владельца проекта (например, канал Slack). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/server.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/server.mdx new file mode 100644 index 000000000000..1bc467404fc4 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/server.mdx @@ -0,0 +1,242 @@ +--- +description: >- + Описывает дополнительные параметры конфигурации самого сервера Dispatch. + Дополнительные параметры конкретных плагинов ищите в документации + плагина. +--- + +# Сервер + +## Первая установка {#first-install} + +Dispatch использует ту же систему конфигурации, что и [Starlette](https://www.starlette.io/config/). + +По умолчанию конфигурация читается из переменных окружения или файлов `.env`. + +:::info +Все параметры с префиксом `VITE_` — переменные окружения для фронтенда на Vue. Они используются только при сборке JavaScript-бандла. Подробности см. [здесь](https://vitejs.dev/guide/env-and-mode.html). На время сборки эти переменные нужно поместить в `src/dispatch/static/dispatch/.env`. +::: + +:::info +Как правило, при указании значений конфигурации не используйте кавычки. +::: + +### Общие {#general} + +#### `LOG_LEVEL` \[по умолчанию: 'WARNING'\] {#log_level-default-warning} + +> Задаёт уровень логирования приложения во время работы. Возможные значения: CRITICAL, ERROR, WARNING, INFO, DEBUG + +#### `STATIC_DIR` \[по умолчанию: 'src/dispatch/static/dispatch/dist'\] {#static_dir-default-srcdispatchstaticdispatchdist} + +> Задаёт, откуда на локальном диске раздаётся статика веб-интерфейса Dispatch. Переменную можно явно установить в `''`, если вы хотите раздавать статику вне сервера Dispatch. + +#### `METRIC_PROVIDERS` \[по умолчанию: ""\] {#metric_providers-default-} + +> Список провайдеров метрик через запятую, куда Dispatch будет отправлять ключевые системные метрики. + +#### `SECRET_PROVIDER` \[по умолчанию: None\] {#secret_provider-default-none} + +> Определяет провайдера для расшифровки секретов конфигурации. Доступные варианты: `kms-secret` и `metatron-secret` + +#### `ENV_TAGS` \[по умолчанию: ""\] {#env_tags-default-} + +> Список тегов через запятую, которые Dispatch попытается взять из окружения. Например, строка `foo:bar,baz:blah` создаст два тега: `foo` со значением переменной окружения `bar` и `baz` со значением переменной окружения `blah`. + +#### `SENTRY_DSN` \[по умолчанию: none\] {#sentry_dsn-default-none} + +> Необязательная настройка для отправки ошибок Dispatch в Sentry. + +#### `MJML_PATH` \[по умолчанию: 'static/dispatch/node_modules/.bin' (относительно каталога пакета)\] {#mjml_path-default-staticdispatchnode_modulesbin-relative-to-the-package-directory} + +> Dispatch использует [MJML](https://mjml.io/documentation/) для генерации HTML-писем. Этому пакету также нужен бинарник `node`, доступный в стандартном пути (или заданный в пути Dispatch). С помощью этой переменной укажите, где Dispatch должен искать команду `mjml`. **Если вы используете стандартный docker-образ Dispatch, это поле нужно вручную установить в путь по умолчанию.** + +#### `DISPATCH_UI_URL` {#dispatch_ui_url} + +> URL административного интерфейса Dispatch; используется в сообщениях для ссылок на него. + +### Аутентификация {#authentication} + +#### `DISPATCH_AUTHENTICATION_PROVIDER_SLUG` \[по умолчанию: dispatch-auth-provider-basic\] {#dispatch_authentication_provider_slug-default-dispatch-auth-provider-basic} + +> Определяет, какой провайдер аутентификации использует Dispatch; по умолчанию Dispatch поставляется с базовым провайдером аутентификации. Также доступен провайдер аутентификации PKCE (`dispatch-auth-provider-pkce`). + +:::info +Если вы хотите отключить аутентификацию, задайте `DISPATCH_AUTHENTICATION_PROVIDER_SLUG=` +::: + +#### Конфигурация `dispatch-auth-provider-basic` {#configuration-for-dispatch-auth-provider-basic} + +:::warning +Сейчас базовая аутентификация позволяет регистрироваться самостоятельно, без подтверждения. +::: + +:::info +Чтобы этот плагин работал, нужно задать `DISPATCH_JWT_SECRET`. +::: + +#### `DISPATCH_JWT_SECRET` {#dispatch_jwt_secret} + +> Используется базовым провайдером аутентификации для выпуска JWT-токенов. + +#### `DISPATCH_JWT_ALG` \[по умолчанию: 'HS256'\] {#dispatch_jwt_alg-default-hs256} + +> Используется базовым провайдером аутентификации для выпуска JWT-токенов. + +#### `DISPATCH_JWT_EXP` \[по умолчанию: 86400 \] {#dispatch_jwt_exp-default-86400-} + +> Используется базовым провайдером аутентификации для выпуска JWT-токенов и задаёт срок их действия. + +#### `DISPATCH_JWT_AUDIENCE` {#dispatch_jwt_audience} + +> Значение `aud`, которое провайдер PKCE требует в id-токене, — обычно это +> client id OIDC. Токены, выпущенные для другого приложения, отклоняются. Если ваш +> провайдер выставляет `aud`, а этот параметр не задан, отклоняется каждый токен. + +#### `DISPATCH_JWT_EMAIL_OVERRIDE` {#dispatch_jwt_email_override} + +> Переопределяет, где Dispatch ищет email пользователя в id-токене. По умолчанию — +> claim `email`. Токен без значения в настроенном claim отклоняется. + +#### `DISPATCH_AUTHENTICATION_DEFAULT_USER` \[по умолчанию: dispatch@example.com\] {#dispatch_authentication_default_user-default-dispatchexamplecom} + +> Используется как анонимный пользователь по умолчанию, когда аутентификация отключена. + +#### Конфигурация `dispatch-auth-provider-pkce` {#configuration-for-dispatch-auth-provider-pkce} + +Это универсальный провайдер OpenID Connect в Dispatch. Он аутентифицирует браузер +по authorization code flow с PKCE и проверяет полученный токен при каждом запросе +к API. Он работает с любым провайдером OIDC, соответствующим спецификации, — Okta, Google, +Keycloak, Microsoft Entra ID. Разобранный пример для Entra см. в разделе +[Аутентификация через Microsoft Entra ID](authentication-entra-id). + +:::info +Чтобы этот плагин работал с вашей настройкой OIDC, нужно задать +`DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS`, +`DISPATCH_AUTHENTICATION_PROVIDER_PKCE_ISSUER` и `DISPATCH_JWT_AUDIENCE`. Кроме того, +могут понадобиться `DISPATCH_JWT_EMAIL_OVERRIDE` и +`DISPATCH_PKCE_DONT_VERIFY_AT_HASH` — в зависимости от того, что выдаёт ваш провайдер. +::: + +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS` {#dispatch_authentication_provider_pkce_jwks} + +> Используется бэкендом аутентификации Dispatch, чтобы получить открытый ключ JSON Web Key Set \(JWKS\) от указанного провайдера. +> Скорее всего, это URL `jwks_uri` вашего провайдера OIDC. +> Обязателен при использовании провайдера аутентификации `dispatch-auth-provider-pkce`. + +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_ISSUER` {#dispatch_authentication_provider_pkce_issuer} + +> Точное значение `iss`, которое выпускает ваш провайдер, например +> `https://login.microsoftonline.com/<tenant-id>/v2.0`. Токены с любым другим +> издателем отклоняются. + +:::warning +Если оставить параметр пустым, будет принят любой издатель, чью подпись подтверждает +настроенный JWKS. Некоторые провайдеры — в том числе Microsoft Entra ID — подписывают +токены всех тенантов общим набором ключей, поэтому без ожидаемого издателя корректная +подпись не говорит, из какого каталога пришёл пользователь. Если выбран провайдер PKCE, +а этот параметр не задан, Dispatch пишет предупреждение в лог при запуске. Значения +по умолчанию у него нет, чтобы существующие деплои продолжали работать, но в новом деплое +его нужно задавать всегда. +::: + +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS_CACHE_SECONDS` \[по умолчанию: 300\] {#dispatch_authentication_provider_pkce_jwks_cache_seconds-default-300} + +> Как долго кешируются ключи подписи провайдера. Ключи также перезапрашиваются +> сразу, когда приходит токен с key id, которого Dispatch ещё не видел, поэтому +> ротация ключа подписи подхватывается, не дожидаясь истечения этого срока. + +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS_TIMEOUT_SECONDS` \[по умолчанию: 5\] {#dispatch_authentication_provider_pkce_jwks_timeout_seconds-default-5} + +> Тайм-аут запроса при загрузке JWKS. Если загрузка не удалась, а ключи уже +> закешированы, продолжают использоваться закешированные ключи — вместо того чтобы отклонять +> каждый запрос, пока провайдер недоступен. + +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_LEEWAY_SECONDS` \[по умолчанию: 60\] {#dispatch_authentication_provider_pkce_leeway_seconds-default-60} + +> Допустимое расхождение часов при проверке `exp`, `nbf` и `iat`. Установите `0`, чтобы требовать +> точного совпадения с часами провайдера идентификации. + +#### `DISPATCH_PKCE_DONT_VERIFY_AT_HASH` \[по умолчанию: false\] {#dispatch_pkce_dont_verify_at_hash-default-false} + +> В зависимости от того, какие значения отправляет ваш провайдер OIDC, может понадобиться установить `true`, чтобы бэкенд Dispatch +> смог декодировать JWT-токен. Принимает только `true`/`false` (или `1`/`0`); +> любое другое значение отклоняется при запуске. + +:::info +Microsoft Entra ID выдаёт `at_hash` только с конечной точки `/authorize` и никогда — при +обмене кода на токен, который использует этот поток, поэтому деплою с Entra этот параметр +не нужен. +::: + +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL` {#dispatch_authentication_provider_pkce_open_id_connect_url} + +> URL well-known-конфигурации вашего провайдера OIDC без завершающего слеша. Используется веб-интерфейсом +> Dispatch для аутентификации пользователя через Proof Key Code Exchange \(PKCE\). + +#### `DISPATCH_AUTHENTICATION_PROVIDER_PKCE_CLIENT_ID` {#dispatch_authentication_provider_pkce_client_id} + +> Client id, который отправляется на конечную точку OpenID Connect. + +#### `DISPATCH_AUTHENTICATION_PROVIDER_USE_ID_TOKEN` \[по умолчанию: false\] {#dispatch_authentication_provider_use_id_token-default-false} + +> Использовать `id_token` вместо `access_token`, принятого по умолчанию. [Подробности](https://developer.okta.com/docs/reference/api/oidc/#tokens-and-claims) +> Зависит от провайдера идентификации. + +#### Конфигурация `dispatch-auth-provider-header` {#configuration-for-dispatch-auth-provider-header} + +> Аутентифицирует пользователей по заголовкам HTTP-запроса. Полезно, когда Dispatch стоит за обратным прокси, который сам выполняет аутентификацию. + +#### `DISPATCH_AUTHENTICATION_PROVIDER_HEADER_NAME` \[по умолчанию: remote-user\] {#dispatch_authentication_provider_header_name-default-remote-user} + +:::info +Убедитесь, что обратный прокси вырезает этот заголовок из входящих (то есть присланных пользователем) запросов. Иначе аутентификацию можно будет обойти. +::: + +> HTTP-заголовок запроса, из которого берётся имя пользователя; регистр не учитывается. + +#### Конфигурация `dispatch-auth-provider-aws-alb` {#configuration-for-dispatch-auth-provider-aws-alb} + +> Аутентифицирует пользователей через [аутентификацию AWS Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html). + +#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_ARN` {#dispatch_authentication_provider_aws_alb_arn} + +> ARN вашего балансировщика; используется для проверки подписанта. +> Формат: `arn:aws:elasticloadbalancing:region-code:account-id:loadbalancer/app/load-balancer-name/load-balancer-id`. +> Обязателен при использовании провайдера аутентификации `dispatch-auth-provider-aws-alb`. + +#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_EMAIL_CLAIM` \[по умолчанию: email\] {#dispatch_authentication_provider_aws_alb_email_claim-default-email} + +> Переопределяет, где Dispatch ищет email пользователя в его claims. + +#### `DISPATCH_AUTHENTICATION_PROVIDER_AWS_ALB_PUBLIC_KEY_CACHE_SECONDS` \[по умолчанию: 300\] {#dispatch_authentication_provider_aws_alb_public_key_cache_seconds-default-300} + +> Переопределяет, как долго Dispatch кеширует открытый ключ, которым проверяется полезная нагрузка. + +:::info +Добавьте действие слушателя ALB без аутентификации для `/api/v1/{organization}/events/*`, если хотите, чтобы плагины были публичными. Плагины сами определяют свою аутентификацию. +::: + +### Хранение данных {#persistence} + +#### `DATABASE_HOSTNAME` {#database_hostname} + +> Dispatch работает с базой данных `Postgres`. Это имя хоста должно указывать на поддерживаемую версию `Postgres` — проект тестируется на `18` и разворачивается с ней; поддерживаемого пути обновления с кластера версии ниже `14` нет. + +#### `DATABASE_CREDENTIALS` \[секрет: True\] {#database_credentials-secret-true} + +> Учётные данные в формате `username:password` для аутентификации в базе данных `postgres`. + +#### `DATABASE_NAME` \[по умолчанию: 'dispatch'\] {#database_name-default-dispatch} + +> Позволяет задать имя базы данных для бэкенда `Dispatch`. + +#### `DATABASE_PORT` \[по умолчанию: '5432'\] {#database_port-default-5432} + +> Позволяет задать порт базы данных для бэкенда `Dispatch`. + +### Модели {#models} + +### Стоимость инцидента {#incident-cost} + +Dispatch [рассчитывает](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L279) стоимость инцидента, суммируя время, которое участники провели в каждой роли инцидента \(например, командир инцидента\), и применяя [множитель вовлечённости](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/service.py#L266), зависящий от роли. Также учитывается время, потраченное на разбор инцидента. Dispatch рассчитывает и публикует стоимость всех инцидентов [каждые 5 минут](https://github.com/helldweller/dispatch/blob/main/src/dispatch/incident/scheduled.py#L257). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/definition.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/definition.mdx new file mode 100644 index 000000000000..0d3d4619d7de --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/definition.mdx @@ -0,0 +1,68 @@ +# Определение сигнала + +Определения сигналов — отправная точка для подключения нового сигнала к Dispatch; они поддерживают множество параметров настройки. + +## Отправка сигналов в Dispatch {#sending-signals-to-dispatch} + +Чтобы отправить сигнал в Dispatch, выполните `POST`-запрос к API по адресу `/{organization}/signals/instances`. + +```python +import requests + +API_TOKEN = "" +API_ENDPOINT = "http://localhost:8080/api/v1/default/signals/instances" + +signal_instance = { + "project": "Test", + "raw": { + "name": "process_events", + "externalId": "someExternalValue", + "id": "<uuid>", # this will be used as the instance's uuid if provided + "variant": "A" , # an additional indicator for signal subtypes + "hostIdentifier": "host1", + "calendarTime": "2022-10-19T10:35:01Z", + "time": 1618698901, + "columns": { + "pid": 888, + "path": "/usr/bin/security", + "cmdline": "/usr/bin/security dump-keychain", + "state": "running", + "parent": 555, + "created_at": 1918698901, + "updated_at": 2118698901 + } + } +} + +requests.Session() +r = session.post( + API_ENDPOINT, + json=signal_instance, + headers={ + "Content-Type": "application/json", + "Authorization": f"Bearer {API_TOKEN}", + }, +) +``` + +:::note + +Полная документация API для `/instances` доступна в [справочнике API](https://helldweller.github.io/dispatch/docs/api#tag/signals/operation/create_signal_instance__organization__signals_instances_post). + +::: + +## Создание определения сигнала {#creating-a-signal-definition} + +В общих чертах вам нужно задать базовые метаданные `signal`: название, описание и вариант. +Также можно указать, должен ли `signal` создавать кейс. Отказ от создания кейса полезен для контекстных сигналов, которые +сами по себе не требуют разбора и расследования. При этом такие сигналы всё равно можно использовать для обогащения других сигналов и кейсов. + +![](/img/admin-ui-signal-definition.png) + +**Вариант (Variant)**: у одного сигнала может быть несколько вариантов с разными определениями. + +**Владелец (Owner)**: как правило, команда или владелец, который порождает сигнал. + +**Внешний идентификатор (External ID)**: по этому идентификатору входящие сигналы сопоставляются с этим определением. Он должен быть уникальным среди всех определений сигналов. + +**Целевой канал (Conversation Target)**: задаёт название канала, в котором будет создан кейс для сигнала. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/engagement-filter.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/engagement-filter.mdx new file mode 100644 index 000000000000..6d804b403958 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/engagement-filter.mdx @@ -0,0 +1,12 @@ +# Фильтр вовлечения + +Фильтры вовлечения (Engagement Filters) автоматизируют обращение к пользователю, причастному к конкретному экземпляру сигнала (Signal Instance). Они используют типы сущностей, которые сопоставляются с адресами электронной почты пользователей в вашем окружении, и настроенное вами сообщение, которое отправляется этим пользователям. Фильтры вовлечения также поддерживают многофакторную аутентификацию при проверке подозрительного поведения. Это полезно, когда нужно убедиться, что пользователь, к которому вы обратились, действительно тот, за кого себя выдаёт, а не злоумышленник. + +### Создание фильтра вовлечения {#creating-an-engagement-filter} + +Чтобы создать фильтр вовлечения, выполните следующие шаги: + +1. Откройте страницу редактирования определения сигнала. +2. Нажмите значок «+» рядом с выпадающим списком «Фильтры вовлечения». + +![](/img/admin-ui-signal-engagement-filter.png) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/entity-type.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/entity-type.mdx new file mode 100644 index 000000000000..b12e66733624 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/entity-type.mdx @@ -0,0 +1,20 @@ +# Тип сущности + +Типы сущностей позволяют извлекать сущности из сырых данных экземпляра сигнала (Signal Instance). Извлечённые сущности сохраняются для дальнейшего использования: на них строятся автоматические корреляции, фильтры вовлечения и фильтры сигналов. + +### Создание типа сущности {#creating-an-entity-type} + +Чтобы создать тип сущности, выполните следующие шаги: + +1. Откройте страницу редактирования определения сигнала. +2. Нажмите значок «+» рядом с выпадающим списком «Типы сущностей». + +После этого в модальном окне откроется песочница типов сущностей (Entity Type playground) — интерактивный инструмент, который помогает создать и проверить тип сущности. Типы сущностей можно строить на регулярных выражениях или в формате JSON Path. + +![](/img/admin-ui-signal-entity-type.png) + +В показанном примере новый тип сущности определён в формате JSON Path. Выражение JSON Path columns.cmdline извлекает значение столбца cmdline из сырых данных экземпляра сигнала. Редактор песочницы подсвечивает извлечённое значение в сырых данных экземпляра сигнала, подтверждая, что совпадение с нужным значением найдено. + +Когда тип сущности вас устроит, перейдите в песочнице к шагу названия и описания. Здесь укажите подходящее название и краткое описание типа сущности. По нажатию «Сохранить» тип сущности будет создан и привязан к соответствующему определению сигнала. + +![](/img/admin-ui-signal-entity-type-name.png) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/filter.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/filter.mdx new file mode 100644 index 000000000000..fe6a69c3ad2e --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/filter.mdx @@ -0,0 +1,46 @@ +# Фильтр + +Фильтры сигналов определяют, как группировать сигналы и когда их отсрочивать (snooze). + +:::note +Чтобы создать фильтр сигналов, сначала определите типы сущностей, по которым сигналы будут дедуплицироваться или отсрочиваться. +::: + +## Фильтр отсрочки {#snooze-filter} + +Фильтры отсрочки (Snooze Filter) используют сущности, извлечённые из сигналов, чтобы определить, когда сигнал нужно отсрочить. Это полезно, когда на некоторое время ожидается наплыв сигналов (например, из-за плановых административных работ) и вы хотите временно остановить создание кейсов. Даже отсроченный сигнал всё равно обрабатывается, а связанные с ним сущности создаются. + +Например, можно создать `Snooze Filter`, который отсрочит все входящие сигналы с определённым хешем JA3. + +:::info +Можно также создать `Snooze Filter` без указания сущностей — тогда он отсрочит все входящие сигналы, подходящие под этот фильтр. +::: + +### Создание фильтра отсрочки {#creating-a-snooze-filter} + +Чтобы создать фильтр отсрочки, выполните следующие шаги: + +1. Откройте страницу редактирования определения сигнала. +2. Нажмите значок «+» рядом с выпадающим списком «Фильтры сигналов». +3. Выберите переключатель `Snooze` на вкладке `BASIC`. + + +![](/img/admin-ui-signal-filter-snooze.png) + +## Фильтр дедупликации {#deduplication-filter} + +Чтобы сигналы дедуплицировались, нужно создать фильтр дедупликации. Фильтры дедупликации используют извлечённые типы сущностей сигнала и скользящее временное окно, чтобы решить, помечать ли сигнал как дубликат. Если совпадение найдено, текущий сигнал помечается как дубликат и привязывается к уже существующему кейсу. + +:::info +По умолчанию все сигналы дедуплицируются в окне в один час, если не задан свой фильтр дедупликации. +::: + +### Создание фильтра дедупликации {#creating-a-deduplication-filter} + +Чтобы создать фильтр дедупликации, выполните следующие шаги: + +1. Откройте страницу редактирования определения сигнала. +2. Нажмите значок «+» рядом с выпадающим списком «Фильтры сигналов». +3. Выберите переключатель `Deduplication` на вкладке `BASIC`. + +![](/img/admin-ui-signal-filter-dedupe.png) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/index.mdx new file mode 100644 index 000000000000..6278d30e4936 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/signal/index.mdx @@ -0,0 +1,7 @@ +--- +sidebar_position: 4 +--- + +# Сигнал + +Сигналы позволяют описать различные события, которые вы принимаете в Dispatch и поднимаете до уровня кейсов. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/templates.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/templates.mdx new file mode 100644 index 000000000000..634042ef0ab7 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/settings/templates.mdx @@ -0,0 +1,115 @@ +# Шаблоны + +Dispatch использует шаблоны, чтобы создавать документацию для конкретного кейса или инцидента. Эти шаблоны копируются и заполняются настолько, насколько Dispatch это умеет. После создания это обычные документы, привязанные к вашему кейсу или инциденту: в них можно работать совместно, фиксировать факты и выводы. + +Dispatch поддерживает несколько типов шаблонов: + +- Кейс (Case) +- Инцидент (Incident) +- Для руководства (Executive) +- Разбор (Review) +- Отслеживание (Tracking) + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-create-edit-template.png) + +</div> +**Название (Name):** название шаблона. + +**Описание (Description):** описание шаблона. + +**Ссылка (Weblink):** ссылка на шаблон. + +**Внешний идентификатор (External Id):** внешний идентификатор шаблона документа. Используется для интеграции через API (например, идентификатор файла Google Doc). Обычно это уникальный идентификатор из ссылки. + +Если включить для шаблона режим evergreen, Dispatch будет отправлять владельцу шаблона напоминание по почте: пора пересмотреть шаблон и убедиться, что он актуален. + +**Владелец evergreen (Evergreen Owner):** адрес электронной почты владельца этого шаблона документа. + +**Интервал напоминаний evergreen (Evergreen Reminder Interval):** число дней между напоминаниями владельцу шаблона документа. + +### Шаблон кейса {#case-template} + +Копия этого шаблона создаётся для каждого нового кейса при его создании. Она содержит текущее состояние кейса; владелец или ответственный по кейсу фиксирует в ней факты и выводы. + +- [Пример документа кейса](https://docs.google.com/document/d/1g1cl9liXG8US0eBnrZYRaeWa7Ek_hoZJ5PPadas44vI) + +#### Переменные шаблона {#template-variables} + +Ниже перечислены переменные, которые Dispatch попытается подставить при создании документа. Обратите внимание: повторно они сейчас не подставляются. + +ПРИМЕЧАНИЕ: все переменные должны быть заключены в `{{}}` + +- `case_name` — название кейса +- `case_title` — заголовок кейса +- `case_description` — описание кейса +- `case_resolution` — решение по кейсу +- `case_owner` — владелец кейса +- `case_type` — тип кейса +- `case_severity` — серьёзность кейса +- `case_priority` — приоритет кейса +- `case_status` — статус кейса +- `case_storage_weblink` — ссылка на хранилище + +### Шаблон инцидента {#incident-template} + +Копия этого шаблона создаётся для каждого нового инцидента при его создании. Она содержит текущее состояние инцидента; участники инцидента делятся в ней знаниями о нём. + +- [Пример документа инцидента](https://docs.google.com/document/d/1fv--CrGpWJJ4nyPR0N0hq4JchHJPuqsXN4azE9CGQiE) + +#### Переменные шаблона {#template-variables-1} + +Ниже перечислены переменные, которые Dispatch попытается подставить при создании документа. Обратите внимание: повторно они сейчас не подставляются. + +ПРИМЕЧАНИЕ: все переменные должны быть заключены в `{{}}` + +- `name` — название инцидента +- `title` — заголовок инцидента +- `description` — описание инцидента +- `resolution` — решение по инциденту +- `commander_fullname` — имя текущего командира инцидента +- `type` — тип инцидента +- `priority` — приоритет инцидента +- `status` — статус инцидента +- `conversation_weblink` — ссылка на канал обсуждения (если есть) +- `conference_weblink` — ссылка на конференцию (если есть) +- `storage_weblink` — ссылка на хранилище (если есть) +- `document_weblink` — ссылка на документ инцидента (если есть) +- `ticket_weblink` — ссылка на тикет инцидента (если есть) + +### Шаблон отчёта для руководства {#executive-template} + +Часто во время инцидента нужно подготовить отчёт для руководства — общий обзор инцидента и действий, которые сейчас предпринимаются. Копия этого шаблона создаётся, заполняется и сохраняется в хранилище инцидента каждый раз, когда составляется новый отчёт для руководства. + +- [Пример отчёта для руководства](https://docs.google.com/document/d/1dab6k14p5ageo5B_d1YlB_zS9hMGHDMXy9RUbIZous4) + +### Шаблон разбора {#review-template} + +Копия этого шаблона создаётся автоматически, когда инцидент помечается как стабильный. Командир инцидента и участники используют её, чтобы свести воедино выводы, обсуждения и задачи после инцидента. + +- [Пример документа разбора инцидента](https://docs.google.com/document/d/1MkCTyheZRtKzMxOBhLgh3PrvarERA9Bwo0joM7D9tmg) + +### Шаблон отслеживания {#tracking-template} + +В некоторых инцидентах нужно отслеживать множество активов; этот шаблон — простая таблица, в которой участники инцидента могут совместно работать с табличными данными. + +- [Пример таблицы отслеживания инцидента](https://docs.google.com/spreadsheets/d/1Odk4KlL7uMF_yd7OvTOCaPWmtTA_WzFBIA4lMeU5cGY) + +### Привязка шаблонов {#template-association} + +Шаблоны кейсов и инцидентов можно привязать к соответствующим типам. Так шаблон точнее соответствует конкретному типу кейса или инцидента и даёт для него дополнительный контекст и указания. + +Кроме того, один шаблон можно привязать к нескольким типам кейсов или инцидентов — например, если вы хотите обойтись одним шаблоном. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-associate-case-template.png) + +</div> + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-associate-incident-template.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/upgrading.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/upgrading.mdx new file mode 100644 index 000000000000..7670d7603f97 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/upgrading.mdx @@ -0,0 +1,45 @@ +--- +sidebar_position: 2 +description: Как не отставать от новых версий. +--- + +# Обновление + +Если вы переходите на новую мажорную версию, сгенерируйте новый конфигурационный файл последней версией Dispatch. Так вы увидите все новые настройки и при необходимости зададите их. + +В остальном обновление сводится к трём шагам: поднять версию Dispatch \(вместе с ней обновятся и изменившиеся зависимости\), выполнить миграции данных и перезапустить все связанные сервисы. + +:::info +В некоторых случаях перед обновлением стоит остановить сервисы, чтобы избежать случайных ошибок. +::: + +## Обновление Dispatch {#upgrading-dispatch} + +### Обновление пакета {#upgrading-the-package} + +Проще всего обновить пакет Dispatch через `pip`: + +```bash +uv pip install --upgrade dispatch +``` + +Возможно, вам удобнее ставить фиксированную версию, а не последнюю: так вы сами контролируете изменения. + +Если вы устанавливаете из исходного кода, у вас могут появиться дополнительные неудовлетворённые зависимости, поэтому проверьте окружение, прежде чем браться за обновление. + +### Выполнение миграций {#running-migrations} + +Как и при первоначальной установке, миграции применяются командой обновления. + +```bash +dispatch database upgrade +``` + +### Перезапуск сервисов {#restarting-services} + +После обновления обязательно перезапустите _все_ сервисы Dispatch. Это необходимо, потому что Python загружает модули в память, и изменения кода не вступят в силу, пока сервисы не перезапущены. + +К этим сервисам относятся: + +- сервер — `dispatch server start` +- планировщик — `dispatch scheduler start` diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/user.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/user.mdx new file mode 100644 index 000000000000..292ace537947 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/administration/user.mdx @@ -0,0 +1,24 @@ +--- +sidebar_position: 3 +--- + +# Управление пользователями + +Пользователи (участники организации) — это учётные записи веб-интерфейса Dispatch; это не то же самое, что контакты (люди) или участники инцидентов. Такие учётные записи служат только для управления доступом к интерфейсу Dispatch. Создавать и удалять пользователей через интерфейс Dispatch пока нельзя — за исключением самостоятельной регистрации. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-users.png) + +</div> + +**Роль:** В интерфейсе Dispatch действует ролевая модель доступа (RBAC). Пока она используется только для защиты чувствительных инцидентов с ограниченной видимостью (restricted). Для конфигурации и настроек Dispatch ограничений доступа пока нет. В Dispatch определены четыре роли: + +- «Участник» (Member): доступ ко всему, кроме инцидентов с ограниченной видимостью, — если только пользователь не участвует в них напрямую. +- «Администратор» (Admin): полный доступ к интерфейсу Dispatch и ко всем инцидентам, независимо от того, открыта их видимость или ограничена. +- «Менеджер» (Manager): пока то же самое, что «Администратор». +- «Владелец» (Owner): полный доступ к интерфейсу Dispatch и к управлению организациями. + +**Настройки:** + +- Проекты по умолчанию (Default Projects): список проектов, по которым Dispatch будет фильтровать данные во всём интерфейсе (например, в таблицах кейсов и инцидентов и на дашбордах). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/changelog.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/changelog.mdx new file mode 100644 index 000000000000..f9dbf29bf948 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/changelog.mdx @@ -0,0 +1,13 @@ +--- +description: Краткое описание изменений. +--- + +# Журнал изменений + +:::info +Dispatch использует схему версий [calver](https://calver.org/). +::: + +Подробнее об изменениях — на странице выпусков в репозитории приложения: + +[Выпуски](https://github.com/helldweller/dispatch/releases) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/support.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/support.mdx new file mode 100644 index 000000000000..e2bb1739f217 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/support.mdx @@ -0,0 +1,24 @@ +--- +description: >- + Мы серьёзно относимся к безопасности Dispatch. Ниже описаны правила, + которые мы приняли, чтобы проблемы безопасности решались + своевременно. +--- + +# Поддержка + +## Общая поддержка {#general-support} + +Поддержку мы оказываем через [трекер задач этого репозитория](https://github.com/helldweller/dispatch/issues). Мы стараемся отвечать быстро, но учтите: открытый исходный код не входит в наши основные обязанности, поэтому код и поддержку мы предоставляем по мере возможностей. + +## Как сообщить о проблеме безопасности {#reporting-a-security-issue} + +Просим не сообщать о проблемах безопасности через обычный трекер задач GitHub. + +Если вы считаете, что нашли уязвимость в `Dispatch`, сообщите о ней приватно через [рекомендации по безопасности GitHub (Security Advisories)](https://github.com/helldweller/dispatch/security/advisories/new). + +> **Примечание.** В кодовой базе нет секретов. Секреты для разработки генерируются локально скриптом `docker/dev-setup.sh` в файл `docker/.env`, исключённый из git; в закоммиченном `docker/.env.example` только заглушки. + +## Поддерживаемые версии {#supported-versions} + +Проект ведёт один сопровождающий по мере сил, без SLA, но сообщения читаются, и по ним принимаются меры. Сообщения об ошибках и уязвимостях принимаются только для **последнего выпуска с тегом** и текущей вершины ветки `main` — полная политика описана в [SECURITY.md](https://github.com/helldweller/dispatch/blob/main/SECURITY.md). diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/cases/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/cases/index.mdx new file mode 100644 index 000000000000..d7f936285ddc --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/cases/index.mdx @@ -0,0 +1,3 @@ +# Кейсы + +Большинству участников интерфейс кейсов Dispatch никогда не понадобится. Но командирам и опытным пользователям этот раздел позволяет искать и фильтровать кейсы и работать с ними, даже если они уже закрыты. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/dashboard/incident.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/dashboard/incident.mdx new file mode 100644 index 000000000000..a92c8d421a13 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/dashboard/incident.mdx @@ -0,0 +1,48 @@ +--- +description: Как получить полезные метрики по инцидентам. +sidebar_position: 1 +--- + +# Инциденты + +## Сводные ключевые метрики {#aggregated-top-line-metrics} + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-dashboard-top-line.png) + +</div> + +Эти метрики агрегируются по всем инцидентам, попавшим под текущий фильтр. + +## Разбивка по ключевым признакам инцидентов {#breakdown-on-key-incident-facets} + +### По типу инцидента {#by-incident-type} + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-dashboard-type.png) + +</div> + +### По приоритету инцидента {#by-incident-priority} + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-dashboard-priority.png) + +</div> + +## Прогнозирование {#forecasting} + +Dispatch умеет строить _простые_ прогнозы. Он смотрит на историю прошлых инцидентов и применяет [экспоненциальное сглаживание](https://machinelearningmastery.com/exponential-smoothing-for-time-series-forecasting-in-python/#:~:text=Exponential%20smoothing%20is%20a%20time%20series%20forecasting%20method%20for%20univariate%20data.&text=Exponential%20smoothing%20forecasting%20methods%20are,decreasing%20weight%20for%20past%20observations), чтобы оценить, сколько инцидентов ждать в будущем. + +При небольшом числе инцидентов прогноз получается посредственным, но с ростом объёма данных он становится точнее. Если данных для разумного прогноза недостаточно, в интерфейсе он не показывается. + +Пример прогноза: + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-dashboard-forecast.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/dashboard/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/dashboard/index.mdx new file mode 100644 index 000000000000..2fd69b9f59d0 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/dashboard/index.mdx @@ -0,0 +1,10 @@ +--- +description: Как получить полезные метрики. +sidebar_position: 1 +--- + +# Дашборды + +В Dispatch есть базовые дашборды и отчёты, которые помогают понять, как инциденты влияют на организацию. Из коробки доступны полезные сводки, например число инцидентов по типу и приоритету. + +Кроме того, все графики на дашбордах динамические. Благодаря этому можно фильтровать данные по разным признакам инцидентов и находить интересные подмножества. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/data.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/data.mdx new file mode 100644 index 000000000000..90bd6afd9b5a --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/data.mdx @@ -0,0 +1,3 @@ +# Данные + +Через раздел «Данные» (Data) вы попадаете во внутренний каталог данных Dispatch. В нём можно хранить метаданные об источниках данных, которые, скорее всего, пригодятся при разрешении инцидентов. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/commander.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/commander.mdx new file mode 100644 index 000000000000..16d8555a44a9 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/commander.mdx @@ -0,0 +1,272 @@ +--- +description: Чего ожидать командиру инцидента. +--- + +# Командир + +## Сообщение об инциденте {#reporting} + +В Dispatch командиры инцидентов \(IC\) тоже являются участниками и получают все сообщения для участников. Когда вас назначают командиром инцидента, вам присваивается эта роль Dispatch, и сведения о вас передаются дальше. + +Ниже перечислены все команды Slack; также можно посмотреть _группы_ команд, связанных с [людьми](#people), [коммуникациями](#communications), [задачами](#tasks) и [ресурсами и метаданными инцидента](#incident-resources-and-metadata). + +## Все команды Slack {#all-slack-commands} + +- [`/dispatch-add-timeline-event`](#dispatch-add-timeline-event) +- [`/dispatch-assign-role`](#dispatch-assign-role) +- [`/dispatch-engage-oncall`](#dispatch-engage-oncall) +- [`/dispatch-list-incidents`](#dispatch-list-incidents) +- [`/dispatch-list-my-tasks`](#dispatch-list-my-tasks) +- [`/dispatch-list-participants`](#dispatch-list-participants) +- [`/dispatch-list-tasks`](#dispatch-list-tasks) +- [`/dispatch-list-workflows`](#dispatch-list-workflows) +- [`/dispatch-notifications-group`](#dispatch-notifications-group) +- [`/dispatch-report-executive`](#dispatch-report-executive) +- [`/dispatch-report-incident`](#dispatch-report-incident) +- [`/dispatch-report-tactical`](#dispatch-report-tactical) +- [`/dispatch-update-incident`](#dispatch-update-incident) +- [`/dispatch-update-participant`](#dispatch-update-participant) +- [`/dispatch-run-workflow`](#dispatch-run-workflow) +- [`/dispatch-create-task`](#dispatch-create-task) +- [`/dispatch-create-case`](#dispatch-create-case) +- [`/dispatch-update-case`](#dispatch-update-case) +- [`/dispatch-escalate-case`](#dispatch-escalate-case) +- [`/dispatch-engage-user`](#dispatch-engage-user) +- [`/dispatch-list-signals`](#dispatch-list-signals) +- [`/dispatch-summary`](#dispatch-summary) + +## Люди {#people} + +Эти команды помогают управлять людьми, которые участвуют в разрешении инцидента. + +### /dispatch-assign-role {#dispatch-assign-role} + +Каждый, кто помогает вести инцидент, может выполнять разные роли. Например, вам может понадобиться протоколист или координатор для руководства, или вы можете передать инцидент новому командиру инцидента. В любом из этих случаев используйте `/dispatch-assign-role`, чтобы быстро назначить роль любому человеку. + +Особенно важно использовать эту команду при передаче командования инцидентом. Так не возникнет путаницы с тем, кто сейчас командир инцидента. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-assign-role.png) + +</div> + +### /dispatch-engage-oncall {#dispatch-engage-oncall} + +Для разрешения инцидента вам понадобится помощь разных команд. Чтобы быстро подключить дежурного из другой команды, используйте `/dispatch-engage-oncall`: команда определит, кто сейчас дежурит, и при желании вызовет его. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-engage-oncall.png) + +</div> + +### /dispatch-list-participants {#dispatch-list-participants} + +С помощью этой команды можно узнать, какие команды и люди подключены к инциденту. Результат выглядит так: + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-list-participants.png) + +</div> + +### /dispatch-update-participant {#dispatch-update-participant} + +Участникам инцидента или командиру инцидента может быть важно знать, в чём специализируется участник и какого вклада в разрешение инцидента от него ждут. Используйте `/dispatch-update-participant`, чтобы обновить причину, по которой участник был добавлен. Диалог выглядит так: + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-update-participant.png) + +</div> + +## Коммуникации {#communications} + +Эти команды помогают управлять коммуникациями по инциденту. + +### /dispatch-notifications-group {#dispatch-notifications-group} + +Группа уведомлений инцидента состоит из отдельных людей или списков рассылки. Управляйте этой группой с помощью `/dispatch-notifications-group.` + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-notifications-group.png) + +</div> + +### /dispatch-report-executive {#dispatch-report-executive} + +Некоторым заинтересованным лицам важен ход инцидента, но прямого участия от них не ждут. Например, финансовый директор может хотеть знать о текущем инциденте безопасности, связанном с финансовыми данными, но вряд ли будет руководить участниками и их действиями. Чтобы держать таких внешних заинтересованных лиц в курсе, используйте `/dispatch-report-executive`: команда поможет составить и разослать отчёт для руководства. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-report-executive.png) + +</div> + +### /dispatch-report-incident {#dispatch-report-incident} + +Используйте `/dispatch-report-incident`, чтобы сообщить о новом инциденте. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-report-incident.png) + +</div> + +### /dispatch-report-tactical {#dispatch-report-tactical} + +Регулярные тактические отчёты, например в формате «Условия, действия, потребности» (Conditions, Actions, and Needs — CAN), крайне важны, чтобы участники были в курсе происходящего. Используйте `/dispatch-report-tactical`, чтобы легко их создавать. + +Форма отчёта выглядит так: + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-status-report.png) + +</div> + +Результат в канале Slack выглядит так: + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-status-report-response.png) + +</div> + +## Задачи {#tasks} + +Dispatch предоставляет лёгкий мост между комментариями Google Docs, назначенными как задачи, и каналом инцидента в Slack. + +В документе инцидента это выглядит так: + +<div style={{textAlign: 'center'}}> + +![](/img/google-docs-task-comment.png) + +</div> + +Следующие команды помогают управлять задачами, связанными с инцидентом. + +### /dispatch-list-my-tasks {#dispatch-list-my-tasks} + +Любой, кто выполнит команду `/dispatch-list-my-tasks`, увидит список задач, которые он создал или которые назначены ему. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-list-my-tasks.png) + +</div> + +### /dispatch-list-tasks {#dispatch-list-tasks} + +Используйте `/dispatch-list-tasks`, чтобы вывести временное сообщение со списком всех задач, связанных с инцидентом. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-list-tasks.png) + +</div> + +## Ресурсы и метаданные инцидента {#incident-resources-and-metadata} + +Эти команды помогают управлять ресурсами и метаданными инцидента (данными об инциденте). + +### /dispatch-update-incident {#dispatch-update-incident} + +Эта команда позволяет командиру инцидента изменить ряд параметров инцидента, не покидая интерфейс обсуждения. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-edit-incident.png) + +</div> + +### /dispatch-add-timeline-event {#dispatch-add-timeline-event} + +Эта команда помогает добавить событие в хронологию инцидента. Можно указать местное время (берётся из вашего профиля Slack) или всемирное координированное время (UTC). + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-add-timeline-event.png) + +</div> + +### /dispatch-list-workflows {#dispatch-list-workflows} + +Эта команда выводит список всех рабочих процессов, связанных с текущим инцидентом. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-list-workflows.png) + +</div> + +### /dispatch-run-workflow {#dispatch-run-workflow} + +Эта команда запускает заранее настроенный рабочий процесс и связывает его артефакты с текущим инцидентом. + +<div style={{textAlign: 'center'}}> + +![](/img/slack-conversation-run-workflow.png) + +</div> + +### /dispatch-create-task {#dispatch-create-task} + +Эта команда создаёт задачу для текущего инцидента. +<div style={{textAlign: 'center'}}> + +{/* TODO(averyl): replace this image */} +![](/img/slack-conversation-create-task.png) + +</div> + +### /dispatch-create-case {#dispatch-create-case} + +Эта команда создаёт кейс для текущего инцидента. + +<div style={{textAlign: 'center'}}> + +</div> + +{/* The sections below have no screenshot yet; capturing one needs a live Slack workspace. See issue #135. */} + +### /dispatch-update-case {#dispatch-update-case} + +Выполните `/dispatch-update-case` в канале кейса, чтобы открыть модальное окно с его названием, описанием, решением и причиной решения, исполнителем, статусом, типом, приоритетом и видимостью. + +Эскалировать кейс отсюда нельзя: в списке статусов намеренно нет `Escalated`. Используйте вместо этого [`/dispatch-escalate-case`](#dispatch-escalate-case) — эта команда создаёт инцидент, в который превращается кейс. + +### /dispatch-escalate-case {#dispatch-escalate-case} + +Выполните `/dispatch-escalate-case` в канале кейса, чтобы превратить его в инцидент. Модальное окно открывается уже заполненным данными кейса — названием, описанием и проектом, — так что можно принять значения по умолчанию или поправить их, а затем выбрать тип, приоритет и серьёзность инцидента. + +Если кейс уже эскалирован, Dispatch сообщит об этом и ничего не сделает: кейс эскалируется только один раз. + +### /dispatch-engage-user {#dispatch-engage-user} + +Выполните `/dispatch-engage-user` в канале кейса, чтобы попросить человека подтвердить свою личность через вашего провайдера многофакторной аутентификации. Типичный случай — сообщение о том, что некая учётная запись сделала что-то, чего её владелец мог и не делать. + +Выберите человека и отредактируйте сообщение, которое он увидит, или оставьте текст по умолчанию. Dispatch добавит его в кейс, если он ещё не участвует, затем отправит запрос и сообщит о результате в канале. Если у человека нет учётной записи в вашем рабочем пространстве Slack, Dispatch напишет об этом в канале. + +### /dispatch-list-incidents {#dispatch-list-incidents} + +Используйте `/dispatch-list-incidents`, чтобы открыть модальное окно со списком всех инцидентов, которые сейчас активны или стабильны, а также инцидентов, закрытых за последние 24 часа. Каждая запись ведёт на инцидент в Dispatch и показывает его командира, проект, статус, тип, серьёзность и приоритет. + +Запущенная в канале инцидента, команда показывает инциденты проекта этого инцидента. Запущенная в любом другом месте — инциденты всех проектов или только одного, если указать его имя: `/dispatch-list-incidents Corporate Security`, где имя — название проекта ровно в том виде, как оно записано в Dispatch. Показать можно только проекты той организации, из которой выполняется команда; аргумента для указания другой организации нет. + +Инциденты с ограниченной видимостью в список не попадают никогда, а окно показывает не больше 49 инцидентов; если в вашей установке их больше, используйте веб-интерфейс Dispatch. + +### /dispatch-list-signals {#dispatch-list-signals} + +Используйте `/dispatch-list-signals`, чтобы узнать, какие определения сигналов отправляют свои кейсы в канал обсуждения, из которого вы выполняете команду. Откроется модальное окно со списком всех определений, чей тип кейса нацелен на этот канал обсуждения; для каждого показаны имя и вариант, а рядом — кнопка [Отсрочить](../../administration/settings/signal/filter.mdx#snooze-filter) (Snooze), которая временно останавливает создание кейсов по этому определению. Длинные списки разбиваются на страницы по 25 записей. + +Команда не принимает аргументов. Если ни один тип кейса не нацелен на этот канал обсуждения, окно сообщит об этом. + +### /dispatch-summary {#dispatch-summary} + +Используйте `/dispatch-summary` в канале инцидента или кейса, чтобы получить сгенерированную ИИ вводную сводку о том, что произошло к этому моменту. Особенно полезно, если вас подключили поздно или вы принимаете инцидент на полпути. Сводку видите только вы, и Dispatch помечает её как сгенерированную ИИ — проверьте её, прежде чем действовать. + +Dispatch откажет и объяснит причину, если вводные сводки не включены для типа инцидента или кейса, если у инцидента или кейса ограниченная видимость или если у кейса нет собственного канала. Если в проекте не включён плагин искусственного интеллекта, Dispatch сообщит только, что сводка недоступна — попросите администратора проверить плагины проекта. diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/feedback.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/feedback.mdx new file mode 100644 index 000000000000..d3e6c10ce7e8 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/feedback.mdx @@ -0,0 +1,27 @@ +# Обратная связь + +При закрытии инцидента Dispatch отправляет всем его участникам личное сообщение с просьбой оценить, насколько они довольны тем, как был отработан инцидент, и оставить обратную связь. Отзывы участников сохраняются и показываются в разделе «Обратная связь» интерфейса, а также раз в день отправляются командиру инцидента по электронной почте. + +#### Личное сообщение {#direct-message} + +<div style={{textAlign: 'center'}}> + +![](/img/user-guide-incident-feedback-conversation-direct-message.png) + +</div> + +#### Окно обратной связи {#feedback-modal} + +<div style={{textAlign: 'center'}}> + +![](/img/user-guide-incident-feedback-conversation-modal.png) + +</div> + +#### Таблица обратной связи в интерфейсе {#feedback-ui-table} + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-feedback.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/forms.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/forms.mdx new file mode 100644 index 000000000000..9a36084ad11b --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/forms.mdx @@ -0,0 +1,80 @@ +--- +description: Как создавать собственные формы инцидентов +--- + +# Формы + +## Создание собственной формы {#creating-a-custom-form} + +Администраторы Dispatch могут создать собственную форму в разделе «Настройки» -> (выберите проект) -> Incident / Form Types. Откроется таблица существующих типов форм (если они есть). Нажмите кнопку NEW, чтобы создать новый тип формы. + +### Схема формы {#form-schema} + +Схема формы — это JSON-массив объектов формы следующего вида: + +| Атрибут | Возможные значения | Примечания | +| -------- | --------------------------- | ------------------------------------------- | +| type | boolean, select, text, date | | +| title | | это текст вопроса | +| if | | условие (см. ниже) | +| name | | уникальная строка-идентификатор | +| multiple | true, false | только для select | +| options | | список вариантов / только для select | +| hint | | показывается мелким текстом (необязательно) | + +Для каждого объекта формы обязательны поля `type`, `title` и `name`. Для типа `select` нужен соответствующий атрибут `options`. + +Примечание: не забудьте включить тип формы (Enabled), иначе он не появится на вкладке форм в инциденте. + +#### Условия {#conditionals} + +Атрибут `if` может содержать сложное логическое выражение на JavaScript. На другие элементы формы ссылайтесь в формате `$<name>`, где `<name>` — уникальный идентификатор из поля name. + +##### Пример {#example} + +``` + [ + { "type": "boolean", "title": "Is this a good form?", "name": "good_form", "hint": "Check if you like"}, + { "type": "select", "if": "$good_form", "title": "How good?", "options": [ "Very much", "A lot", "It's ok" ], "multiple": false, "name": "like_level"}, + { "type": "text", "if": "$good_form && $like_level && $like_level.includes('A lot')", "title": "Provide more feedback", "name": "feedback"} + ] +``` + +## Заполнение формы в инциденте {#fill-out-a-form-in-an-incident} + +После открытия инцидента перейдите на панель «Просмотр/Редактирование» (View/Edit) и выберите вверху вкладку «Формы» (Forms). Здесь перечислены все формы, заполненные к этому моменту. Форма может быть в состоянии «Черновик» (Draft) или «Завершена» (Completed). Можно отредактировать существующую форму или создать новую на основе любого из включённых типов форм, созданных, как описано выше. + +Пока форма заполняется, пользователь может нажать **Отмена** (Cancel), чтобы отбросить изменения, **Сохранить как черновик** (Save as Draft), чтобы сохранить введённые данные со статусом _Черновик_, или **Отправить** (Submit), чтобы сохранить форму со статусом _Завершена_. + +## Юридическая проверка {#attorney-review} + +Новая вкладка «Формы» в меню слева показывает все формы в состоянии _Черновик_ и _Завершена_ для проверки руководством и юристами. Для каждой формы доступны просмотр/редактирование, удаление и особый пункт **Юридическая проверка** (Attorney Review). Он показывает нужные сведения об инциденте и значения, внесённые в форму, а также выпадающий список статуса юридической проверки и два новых поля — для заметок юриста и открытых вопросов. + +## Дополнительные вопросы юристов {#additional-attorney-questions} + +Если юристам для оценки сведений из формы нужны дополнительные вопросы, у каждого типа формы есть возможность задать дополнительные вопросы юристов. Их схема повторяет формат основной схемы формы. Дополнительные вопросы юристов появляются только в разделе для юристов при выполнении юридической проверки со страницы «Формы». + +![](/img/attorney-section.png) + +## Схема оценки {#scoring-schema} + +На основе ответов в форме можно рассчитать оценку риска. Схема оценки — это JSON-массив объектов следующего вида: + +| Атрибут | Тип | Примечания | +| -------- | ---- | --------------------------------- | +| var | text | соответствующая переменная формы | +| includes | list | JSON-список выбранных вариантов | +| score | int | добавляемые баллы | + +Если данные формы, соответствующие `var`, содержат хотя бы один элемент из списка `includes`, то значение `score` прибавляется к оценке риска. Учтите, что сейчас баллы не накапливаются: если в данных формы два элемента из списка, оценка добавляется только один раз. Например, при схеме формы из примера выше и схеме оценки ниже, если пользователь выберет «Very much», оценка риска будет равна 10. + +``` + [ + { "var": "like_level", "includes": [ "Very much", "A lot" ], "score": 10}, + { "var": "like_level", "includes": [ "It's ok" ], "score": 1}, + ] +``` + +Оценка риска показывается на вкладке «Формы» в столбце «Оценка риска» (Risk Score), а также в сводке для юристов на карточке «Юридическая проверка». + +![](/img/example-risk-score.png) diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/index.mdx new file mode 100644 index 000000000000..8c46d6af4022 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/index.mdx @@ -0,0 +1,13 @@ +--- +sidebar_position: 2 +--- + +# Инциденты + +Большинству участников интерфейс инцидентов Dispatch никогда не понадобится. Но командирам и опытным пользователям этот раздел позволяет искать и фильтровать инциденты и работать с ними, даже если они уже закрыты. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incidents.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/participant.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/participant.mdx new file mode 100644 index 000000000000..070d0c0827d8 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/participant.mdx @@ -0,0 +1,83 @@ +--- +description: Чего ожидать участнику инцидента. +--- + +# Участник + +## Сообщение об инциденте {#reporting} + +Dispatch старается сделать так, чтобы сообщить об инциденте было как можно проще. Для этого есть отдельная форма сообщения об инциденте: любой сотрудник организации может заполнить её и подключить ресурсы для работы с инцидентом. + +Адрес формы: `https://<your-dispatch-domain>/default/incidents/report` + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-report.png) + +</div> + +После отправки пользователь видит все ресурсы инцидента, которые нужны, чтобы начать им управлять. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-report-receipt.png) + +</div> + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-incident-report-resources.png) + +</div> + +## Во время инцидента {#during} + +После создания инцидента Dispatch автоматически подключает новых участников. Кого именно подключать, определяют правила, заданные в интерфейсе администратора Dispatch. + +Каждый новый участник получает приветственное сообщение \(по электронной почте и в Slack\) с ресурсами и сведениями, которые помогут ему сориентироваться в этом инциденте. + +<div style={{textAlign: 'center'}}> + +![Приветственное письмо об инциденте](/img/email-incident-welcome.png) + +</div> + +<div style={{textAlign: 'center'}}> + +![Приветственное сообщение об инциденте в Slack (временное)](https://lh4.googleusercontent.com/EgiaPr7p7X-MsmhU7LCNn9BoM0qgqlj-yFBRsxHYGFY6GWSVmYkqNjDzFB-iTNpZBlaxjpVJ_R8HC5jO9gu12ehtIGfT3-7At7lQms-dppkxiFZTyOA8LUQyubCDqLAU23NYwcoQfrw) + +</div> + +На протяжении всего инцидента Dispatch управляет ресурсами, необходимыми для расследования, а также присылает напоминания и уведомления. + +## После инцидента {#after} + +После того как инцидент помечен как стабильный, Dispatch продолжает помогать в управлении им и создаёт дополнительные ресурсы, например документы постинцидентного разбора \(Post Incident Review, PIR\). + +## Уведомления {#notifications} + +Помимо подключения людей, которые будут напрямую отвечать за управление инцидентом, Dispatch рассылает уведомления, чтобы организация в целом была в курсе происходящего. + +:::info +Если в проекте включено самостоятельное присоединение (Self-Join), в уведомлении о новом инциденте есть кнопка «Присоединиться» (Join): с её помощью можно добавить себя в инцидент \(и получить доступ к его ресурсам\) без участия командира инцидента. +::: + +## Самостоятельное подключение {#self-service-engagement} + +Часто участники хотят «подписаться» на инциденты по определённому набору параметров. Dispatch позволяет подключать людей к инцидентам автоматически по таким параметрам. + +Чтобы настроить подключение человека, откройте `Contact > Individual` и отредактируйте существующий контакт или создайте новый. + +Затем задайте условия подключения: выберите или добавьте термины и фразы, при обнаружении которых в атрибутах инцидента этот человек будет приглашён в инцидент. + +Подробнее о подключении к инцидентам читайте [здесь](../../administration/settings/contact/index.mdx). + +### Как это работает {#how-it-works} + +Для любого набора параметров (тип инцидента, приоритет инцидента, название, описание и т. д.) Dispatch попытается подключить каждого человека, связанного с этими параметрами. Сейчас термины связываются по принципу «ИЛИ»: если совпал хотя бы один термин, человек будет добавлен в инцидент. + +По мере развития инцидента появляется новая информация. При любом изменении этих параметров Dispatch заново проверяет связи и при необходимости добавляет новых людей. + +Например, возьмём инцидент, о котором сообщили как об «утечке учётных данных» (Credential Leak). Dispatch подключит всех, у кого заданы термины «Credential», «Leak» и «Credential Leak» (регистр и знаки препинания не учитываются). + +Если же в ходе расследования выяснится, что на самом деле это «компрометация системы» (System Compromise), и мы соответственно изменим описание и название, Dispatch подтянет людей, связанных с терминами «System», «Compromise» и «System Compromise». diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/tasks.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/tasks.mdx new file mode 100644 index 000000000000..6e5791a2f516 --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/incidents/tasks.mdx @@ -0,0 +1,9 @@ +# Задачи + +Как и сам инцидент, его задачи ведутся прямо в канале инцидента. Но когда нужно посмотреть все задачи по инцидентам во всей организации, это можно сделать в этом разделе. + +<div style={{textAlign: 'center'}}> + +![](/img/admin-ui-tasks.png) + +</div> diff --git a/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/index.mdx b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/index.mdx new file mode 100644 index 000000000000..070fe30f7e2b --- /dev/null +++ b/docs/i18n/ru/docusaurus-plugin-content-docs/current/user-guide/index.mdx @@ -0,0 +1,14 @@ +--- +title: Введение +sidebar_position: 0 +--- + +# Руководство пользователя + +В Dispatch есть два _основных_ типа пользователей: командир инцидента и участник инцидента. + +Командир инцидента отвечает за то, чтобы довести инцидент до разрешения. В спорных вопросах его голос решающий, и он обязан понимать контекст инцидента _целиком_. В зависимости от команды и масштаба инцидента он также распределяет задачи и задаёт вопросы другим участникам инцидента. + +Участники инцидента — профильные эксперты (SME), которых привлекают к инциденту, чтобы решать задачи или отвечать на вопросы командира инцидента. + +Дальше вы узнаете подробнее, как каждый из них взаимодействует с Dispatch. diff --git a/docs/i18n/ru/docusaurus-theme-classic/footer.json b/docs/i18n/ru/docusaurus-theme-classic/footer.json new file mode 100644 index 000000000000..e16ad783ad2d --- /dev/null +++ b/docs/i18n/ru/docusaurus-theme-classic/footer.json @@ -0,0 +1,18 @@ +{ + "link.title.More": { + "message": "Ещё", + "description": "The title of the footer links column with title=More in the footer" + }, + "link.item.label.Changelog": { + "message": "Журнал изменений", + "description": "The label of footer link with label=Changelog linking to /docs/changelog" + }, + "link.item.label.License": { + "message": "Лицензия", + "description": "The label of footer link with label=License linking to /docs/license" + }, + "copyright": { + "message": "© 2026 Документация Dispatch. Собрано на Docusaurus.", + "description": "The footer copyright" + } +} diff --git a/docs/i18n/ru/docusaurus-theme-classic/navbar.json b/docs/i18n/ru/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000000..e51154b429ec --- /dev/null +++ b/docs/i18n/ru/docusaurus-theme-classic/navbar.json @@ -0,0 +1,22 @@ +{ + "title": { + "message": "Dispatch", + "description": "The title in the navbar" + }, + "item.label.User Guide": { + "message": "Руководство пользователя", + "description": "Navbar item with label User Guide" + }, + "item.label.Administration": { + "message": "Администрирование", + "description": "Navbar item with label Administration" + }, + "item.label.API": { + "message": "API", + "description": "Navbar item with label API" + }, + "item.label.Support": { + "message": "Поддержка", + "description": "Navbar item with label Support" + } +}