From 022df090e59b5325d442cf850d094e667800073a Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Mon, 13 Jun 2022 17:31:32 -0300 Subject: [PATCH 01/18] Minor README and GOVERNANCE updates --- GOVERNANCE.md | 23 +++++++++++++++-------- README.md | 4 ++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 6b837d68..9a63fb65 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -22,7 +22,7 @@ The OnCall developers and community are expected to follow the values defined in ## Projects -Each project must have a [`MAINTAINERS.md`][maintainers] file with at least one maintainer. Where a project has a release process, access and documentation should be such that more than one person can perform a release. Releases should be announced on the [announcements][https://github.com/grafana/oncall/discussions/categories/announcements] category at the GitHub Discussions. Any new projects should be first proposed on the [team mailing list][team] following the voting procedures listed below. +Each project must have a [`MAINTAINERS.md`][maintainers] file with at least one maintainer. Where a project has a release process, access and documentation should be such that more than one person can perform a release. Releases should be announced on the [announcements][announce] category at the GitHub Discussions. Any new projects should be first proposed on the [team mailing list][team] following the voting procedures listed below. ## Decision making @@ -57,7 +57,6 @@ The current team members are: - Yulia Shanyrova — [@Ukochka](https://github.com/Ukochka) ([Grafana Labs](https://grafana.com/)) - Maxim Mordasov — [@maskin25](https://github.com/maskin25) ([Grafana Labs](https://grafana.com/)) - Julia Artyukhina — [@Ferril](https://github.com/Ferril) ([Grafana Labs](https://grafana.com/)) -- Julia Artyukhina — [@Ferril](https://github.com/Ferril) ([Grafana Labs](https://grafana.com/)) Previous team members: @@ -67,7 +66,7 @@ Previous team members: Maintainers lead one or more project(s) or parts thereof and serve as a point of conflict resolution amongst the contributors to this project. Ideally, maintainers are also team members, but exceptions are possible for suitable maintainers that, for whatever reason, are not yet team members. -Changes in maintainership have to be announced on the [announcemount][https://github.com/grafana/oncall/discussions/categories/announcements] category at the GitHub Discussions. They are decided by [rough consensus](#consensus) and formalized by changing the [`MAINTAINERS.md`][maintainers] file of the respective repository. +Changes in maintainership have to be announced on the [announcemount][announce] category at the GitHub Discussions. They are decided by [rough consensus](#consensus) and formalized by changing the [`MAINTAINERS.md`][maintainers] file of the respective repository. Maintainers are granted commit rights to all projects covered by this governance. @@ -77,7 +76,7 @@ A project may have multiple maintainers, as long as the responsibilities are cle ### Technical decisions -Technical decisions that only affect a single project are made informally by the maintainer of this project, and [rough consensus](#consensus) is assumed. Technical decisions that span multiple parts of the project should be discussed and made on the the [GitHub Discussions][https://github.com/grafana/oncall/discussions]. +Technical decisions that only affect a single project are made informally by the maintainer of this project, and [rough consensus](#consensus) is assumed. Technical decisions that span multiple parts of the project should be discussed and made on the the [GitHub Discussions][discussions]. Decisions are usually made by [rough consensus](#consensus). If no consensus can be reached, the matter may be resolved by [majority vote](#majority-vote). @@ -87,7 +86,7 @@ Changes to this document are made by Grafana Labs. ### Other matters -Any matter that needs a decision may be called to a vote by any member if they deem it necessary. For private or personnel matters, discussion and voting takes place on the [team mailing list][team], otherwise on the [GitHub Discussions][https://github.com/grafana/oncall/discussions]. +Any matter that needs a decision may be called to a vote by any member if they deem it necessary. For private or personnel matters, discussion and voting takes place on the [team mailing list][team], otherwise on the [GitHub Discussions][discussions]. ## Voting @@ -99,7 +98,7 @@ For all votes, voting must be open for at least one week. The end date should be In all cases, all and only [team members](#team-members) are eligible to vote, with the sole exception of the forced removal of a team member, in which said member is not eligible to vote. -Discussion and votes on personnel matters (including but not limited to team membership and maintainership) are held in private on the [team mailing list][team]. All other discussion and votes are held in public on the [GitHub Discussions][https://github.com/grafana/oncall/discussions]. +Discussion and votes on personnel matters (including but not limited to team membership and maintainership) are held in private on the [team mailing list][team]. All other discussion and votes are held in public on the [GitHub Discussions][discussions]. For public discussions, anyone interested is encouraged to participate. Formal power to object or vote is limited to [team members](#team-members). @@ -107,7 +106,7 @@ For public discussions, anyone interested is encouraged to participate. Formal p The default decision making mechanism for the OnCall project is [rough][rough] consensus. This means that any decision on technical issues is considered supported by the [team][team] as long as nobody objects or the objection has been considered but not necessarily accommodated. -Silence on any consensus decision is implicit agreement and equivalent to explicit agreement. Explicit agreement may be stated at will. Decisions may, but do not need to be called out and put up for decision on the [GitHub Discussions][https://github.com/grafana/oncall/discussions] at any time and by anyone. +Silence on any consensus decision is implicit agreement and equivalent to explicit agreement. Explicit agreement may be stated at will. Decisions may, but do not need to be called out and put up for decision on the [GitHub Discussions][discussions] at any time and by anyone. Consensus decisions can never override or go against the spirit of an earlier explicit vote. @@ -142,7 +141,7 @@ If there are multiple alternatives, members may vote for one or more alternative The new member is - added to the list of [team members](#team-members). Ideally by sending a PR of their own, at least approving said PR. -- announced on the [GitHub Discussions][https://github.com/grafana/oncall/discussions] by an existing team member. Ideally, the new member replies in this thread, acknowledging team membership. +- announced on the [GitHub Discussions][discussions] by an existing team member. Ideally, the new member replies in this thread, acknowledging team membership. - added to the projects with commit rights. - added to the [team mailing list][team]. @@ -157,3 +156,11 @@ The ex-member is - added to a list of previous members if they so choose. If needed, we reserve the right to publicly announce removal. + + +[announce]: https://github.com/grafana/oncall/discussions/categories/announcements +[coc]: https://github.com/grafana/oncall/blob/dev/CODE_OF_CONDUCT.md +[maintainers]: https://github.com/grafana/oncall/blob/dev/MAINTAINERS.md +[rough]: https://tools.ietf.org/html/rfc7282 +[discussions]: https://github.com/grafana/oncall/discussions/ +[team]: TBD diff --git a/README.md b/README.md index 6e94081a..a71f98f1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ We prepared multiple environments: [production](https://grafana.com/docs/grafana 1. Download docker-compose.yaml: ```bash -curl https://github.com/grafana/oncall/blob/dev/docker-compose.yml -o docker-compose.yaml +curl https://raw.githubusercontent.com/grafana/oncall/dev/docker-compose.yml -o docker-compose.yaml ``` 2. Set variables: @@ -39,7 +39,7 @@ docker-compose --env-file .env_hobby -f docker-compose.yml up --build -d docker-compose --env-file .env_hobby -f docker-compose.yml run engine python manage.py issue_invite_for_the_frontend --override ``` -5. Go to [OnCall Plugin Configuration](http://localhost:3000/plugins/grafana-oncall-app) (or find OnCall plugin in configuration->plugins) and connect OnCall _plugin_ with OnCall _backend_: +5. Go to [OnCall Plugin Configuration](http://localhost:3000/plugins/grafana-oncall-app), using log in credentials as defined above: `admin`/`admin` (or find OnCall plugin in configuration->plugins) and connect OnCall _plugin_ with OnCall _backend_: ``` Invite token: ^^^ from the previous step. OnCall backend URL: http://engine:8080 From 86eef306463d6858759c57c592937e5772fb9dfe Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Mon, 13 Jun 2022 17:40:39 -0300 Subject: [PATCH 02/18] Remove confusing cloud in instance heartbeat --- grafana-plugin/src/pages/cloud/CloudPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grafana-plugin/src/pages/cloud/CloudPage.tsx b/grafana-plugin/src/pages/cloud/CloudPage.tsx index d81ce0c9..6bf7bf37 100644 --- a/grafana-plugin/src/pages/cloud/CloudPage.tsx +++ b/grafana-plugin/src/pages/cloud/CloudPage.tsx @@ -237,7 +237,7 @@ const CloudPage = observer((props: CloudPageProps) => { - Monitor cloud instance with heartbeat + Monitor instance with heartbeat Once connected, current OnCall instance will send heartbeats every 3 minutes to the cloud Instance. If no @@ -354,7 +354,7 @@ const CloudPage = observer((props: CloudPageProps) => { - Monitor cloud instance with heartbeat + Monitor instance with heartbeat Once connected, current OnCall instance will send heartbeats every 3 minutes to the cloud Instance. If no From b6109dea4f3ee71cf30711a0c49ec63cc69c3664 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Mon, 13 Jun 2022 18:08:11 -0300 Subject: [PATCH 03/18] Fix typo --- grafana-plugin/src/pages/cloud/CloudPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grafana-plugin/src/pages/cloud/CloudPage.tsx b/grafana-plugin/src/pages/cloud/CloudPage.tsx index 6bf7bf37..81b1e61e 100644 --- a/grafana-plugin/src/pages/cloud/CloudPage.tsx +++ b/grafana-plugin/src/pages/cloud/CloudPage.tsx @@ -273,7 +273,7 @@ const CloudPage = observer((props: CloudPageProps) => {
{ - 'Ask your users to sign up in Grafana Cloud, verify phone number and feel free to set up SMS & phone call notificaitons in personal settings! Only users with Admin or Editor role will be synced.' + 'Ask your users to sign up in Grafana Cloud, verify phone number and feel free to set up SMS & phone call notifications in personal settings! Only users with Admin or Editor role will be synced.' } From cd0c8ac722aabbfac17c7511f18199d18f45e80e Mon Sep 17 00:00:00 2001 From: alyssa wada Date: Tue, 14 Jun 2022 16:52:36 -0600 Subject: [PATCH 04/18] OnCall open source edits --- docs/sources/open-source.md | 104 +++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 32 deletions(-) diff --git a/docs/sources/open-source.md b/docs/sources/open-source.md index a95c21eb..ad373fd9 100644 --- a/docs/sources/open-source.md +++ b/docs/sources/open-source.md @@ -8,26 +8,48 @@ title: Open Source weight: 300 --- -# Open Source +# Grafana OnCall Open Source guide -We prepared three environments for OSS users: -- **Hobby** environment for local usage & playing around: [README.md](https://github.com/grafana/oncall#getting-started). +Grafana OnCall is a developer-friendly incident response tool that's available to Grafana open source and Grafana Cloud users. The OSS version of Grafana OnCall provides the same reliable on-call management solution along with the flexibility of a self-managed environment. + +This guide describes the necessary installation and configuration steps needed to configure OSS Grafana OnCall. + +The intended audience for this guide includes: +- Grafana open source admins who are responsible for deploying and configuring Grafana OnCall. +- Grafana open source users who need to configure SMS and phone notifications using Grafana Cloud. + +## Install Grafana OnCall OSS + +There are three Grafana OnCall OSS environments available: + +- **Hobby** playground environment for local usage: [README.md](https://github.com/grafana/oncall#getting-started) - **Development** environment for contributors: [DEVELOPER.md](https://github.com/grafana/oncall/blob/dev/DEVELOPER.md) -- **Production** environment for reliable cloud installation using Helm: [Production Environment](#production-environment) +- **Production** environment for reliable cloud installation: [Production Environment](#production-environment) -## Production Environment +For detailed installation instructions and additional resources, refer to the OSS Grafana OnCall [README.md](https://github.com/grafana/oncall#getting-started) -We prepared the helm chart for production environment: https://github.com/grafana/oncall/helm +For more information on production environment installation, refer to the following OSS Grafana OnCall [production environment helm chart](https://github.com/grafana/oncall/helm) -## Slack Setup -Grafana OnCall Slack integration use a lot of Slack API features: -- Subscription on Slack events requires OnCall to be externally available and provide https endpoint. -- You will need to register new Slack App. +## Slack integration for Grafana OnCall OSS -1. Make sure your OnCall is up and running. +The Slack integration for Grafana OnCall leverages Slack API features to provide a customizable and useful integration. + +### Before you begin + +Review the following requirements to configure Slack for Grafana OnCall OSS: + +- Ensure your Grafana OnCall environment is running. +- Grafana OnCall must be externally available and provide HTTPS endpoint to establish subscription on Slack events. +- Create a new Slack App from Grafana OnCall app manifest. + +### Configure Slack for Grafana OnCall OSS + +1. Ensure your Grafana OnCall environment is up and running. + +2. Grafana OnCall must be accessible through HTTPS. For development purposes, it's recommend to use [localtunnel](https://github.com/localtunnel/localtunnel). For production purposes, consider establishing a proper web server with HTTPS termination. +For localtunnel, refer to the following configuration: -2. You need OnCall to be accessible through https. For development purposes we suggest using [localtunnel](https://github.com/localtunnel/localtunnel). For production purposes please consider setting up proper web server with HTTPS termination. For localtunnel: ```bash # Choose the unique prefix instead of pretty-turkey-83 # Localtunnel will generate an url, e.g. https://pretty-turkey-83.loca.lt @@ -35,15 +57,15 @@ Grafana OnCall Slack integration use a lot of Slack API features: lt --port 8080 -s pretty-turkey-83 --print-requests ``` -3. If you use localtunnel, open your external URL and click "Continue" to allow requests to bypass the warning page. +3. If using localtunnel, open your external URL and click **Continue** to allow requests to bypass the warning page. 4. [Create a Slack Workspace](https://slack.com/create) for development, or use your company workspace. -5. Go to https://api.slack.com/apps and click Create New App button +5. Go to https://api.slack.com/apps and click **Create New App** -6. Select `From an app manifest` option and choose the right workspace +6. Select `From an app manifest` option and select your workspace. -7. Copy and paste the following block with the correct and fields +7. Copy and paste the following block. Be sure to replace `YOUR_BOT_NAME` and `ONCALL_ENGINE_PUBLIC_URL` fields with the appropriate information. ```yaml _metadata: @@ -133,7 +155,7 @@ lt --port 8080 -s pretty-turkey-83 --print-requests socket_mode_enabled: false ``` -6. Go to your "OnCall" -> "Env Variables" and set: +6. Set environment variables by navigating to your Grafana OnCall, then click **Env Variables** and set the following: ``` SLACK_CLIENT_OAUTH_ID = Basic Information -> App Credentials -> Client ID SLACK_CLIENT_OAUTH_SECRET = Basic Information -> App Credentials -> Client Secret @@ -141,30 +163,48 @@ lt --port 8080 -s pretty-turkey-83 --print-requests SLACK_INSTALL_RETURN_REDIRECT_HOST = << OnCall external URL >> ``` -7. Go to "OnCall" -> "ChatOps" -> "Slack" and install Slack Integration +7. From OnCall, navigate to **ChatOps**, select Slack and click **Install Slack integration**. -8. All set! +8. Configure additional Slack settings as needed and your integration is ready for use. -## Telegram Setup +## Telegram integration for Grafana OnCall OSS -- Telegram integrations requires OnCall to be externally available and provide https endpoint. -- Telegram integration in OnCall is designed for collaborative team work. It requires Telegram Group and a Telegram Channel (private) for alerts. +The Telegram integration for Grafana OnCall is designed for collaborative team work and improved incident response. +### Before your begin -1. Make sure your OnCall is up and running. +Review the following requirements to configure Telegram for Grafana OnCall OSS: +- Ensure your Grafana OnCall environment is running. +- Grafana OnCall must be externally available and provide HTTPS endpoint to establish subscription on Telegram events. +- Create new Telegram Group and private Telegram channel for alerts. -2. Respectfully ask [BotFather](https://t.me/BotFather) for a key, put it in `TELEGRAM_TOKEN` in "OnCall" -> "Env Variables". +### Configure Telegram for Grafana OnCall OSS -3. Set `TELEGRAM_WEBHOOK_HOST` with your external url for OnCall. +1. Ensure your OnCall environment is up and running. -4. Go to "OnCall" -> "ChatOps" -> Telegram and enjoy! +2. Request [BotFather](https://t.me/BotFather) for a key, then add your key in `TELEGRAM_TOKEN` in your Grafana OnCall **Env Variables**. -## Grafana OSS-Cloud Setup +3. Set `TELEGRAM_WEBHOOK_HOST` with your external URL for your Grafana OnCall. -Grafana OSS could be connected to Grafana Cloud for heartbeat and SMS / Phone Calls. We tried our best in making Grafana OSS <-> Cloud self-explanatory. Check "Cloud" page in your OSS OnCall instance. +4. From the **ChatOps** tab in Grafana OnCall, click **Telegram** and your integration is now ready for use. -Please note that it's possible either to use Grafana Cloud either Twilio for SMS/Phone calls. +## Connect Grafana Cloud to Grafana OnCall OSS -## Twilio Setup +Open source Grafana OnCall can be connected to Grafana Cloud to configure a variety of notifications. -1. Make sure Grafana OSS <-> Cloud connector is disabled. Set `GRAFANA_CLOUD_NOTIFICATIONS_ENABLED` as False. -2. Check "OnCall" -> "Env Variables" and set all variables starting with `TWILIO_` +The benefits of connecting to Grafana Cloud include: +- Heartbeat notification +- SMS for user notifications +- Phone calls for user notifications. + +To connect to Grafana Cloud, refer to the **Cloud** page in your OSS Grafana OnCall instance. + + +>**NOTE:** As an alternative option to Grafana Cloud, phone call and SMS notifications can be configured using Twilio. + + +## Connect Twilio for Grafana OnCall OSS + +Grafana OnCall supports Twilio SMS and phone call notifications delivery. If you prefer to configure SMS and phone call notifications using Twilio, complete the following steps: + +1. Set `GRAFANA_CLOUD_NOTIFICATIONS_ENABLED` as **False** to ensure the Grafana OSS <-> Cloud connector is disabled. +2. From your **OnCall** environment, select **Env Variables** and configure all variables starting with `TWILIO_`. From 4d7d8172347964ba0ec87acedcc5dea6b09c6a6a Mon Sep 17 00:00:00 2001 From: Alyssa Wada <101596687+alyssawada@users.noreply.github.com> Date: Thu, 16 Jun 2022 16:09:42 -0600 Subject: [PATCH 05/18] Apply suggestions from code review Co-authored-by: Eve Meelan <81647476+Eve832@users.noreply.github.com> --- docs/sources/open-source.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/sources/open-source.md b/docs/sources/open-source.md index ad373fd9..4bb9d753 100644 --- a/docs/sources/open-source.md +++ b/docs/sources/open-source.md @@ -8,7 +8,7 @@ title: Open Source weight: 300 --- -# Grafana OnCall Open Source guide +# Grafana OnCall open source guide Grafana OnCall is a developer-friendly incident response tool that's available to Grafana open source and Grafana Cloud users. The OSS version of Grafana OnCall provides the same reliable on-call management solution along with the flexibility of a self-managed environment. @@ -24,7 +24,7 @@ There are three Grafana OnCall OSS environments available: - **Hobby** playground environment for local usage: [README.md](https://github.com/grafana/oncall#getting-started) - **Development** environment for contributors: [DEVELOPER.md](https://github.com/grafana/oncall/blob/dev/DEVELOPER.md) -- **Production** environment for reliable cloud installation: [Production Environment](#production-environment) +- **Production** environment for reliable Cloud installation: [Production Environment](#production-environment) For detailed installation instructions and additional resources, refer to the OSS Grafana OnCall [README.md](https://github.com/grafana/oncall#getting-started) @@ -47,7 +47,7 @@ Review the following requirements to configure Slack for Grafana OnCall OSS: 1. Ensure your Grafana OnCall environment is up and running. -2. Grafana OnCall must be accessible through HTTPS. For development purposes, it's recommend to use [localtunnel](https://github.com/localtunnel/localtunnel). For production purposes, consider establishing a proper web server with HTTPS termination. +1. Grafana OnCall must be accessible through HTTPS. For development purposes, use [localtunnel](https://github.com/localtunnel/localtunnel). For production purposes, consider establishing a proper web server with HTTPS termination. For localtunnel, refer to the following configuration: ```bash @@ -57,15 +57,15 @@ For localtunnel, refer to the following configuration: lt --port 8080 -s pretty-turkey-83 --print-requests ``` -3. If using localtunnel, open your external URL and click **Continue** to allow requests to bypass the warning page. +1. If using localtunnel, open your external URL and click **Continue** to allow requests to bypass the warning page. -4. [Create a Slack Workspace](https://slack.com/create) for development, or use your company workspace. +1. [Create a Slack Workspace](https://slack.com/create) for development, or use your company workspace. -5. Go to https://api.slack.com/apps and click **Create New App** +1. Go to https://api.slack.com/apps and click **Create an App** . -6. Select `From an app manifest` option and select your workspace. +1. Select `From an app manifest` option and select your workspace. -7. Copy and paste the following block. Be sure to replace `YOUR_BOT_NAME` and `ONCALL_ENGINE_PUBLIC_URL` fields with the appropriate information. +1. Replace the text with the following YAML code block . Be sure to replace `` and `` fields with the appropriate information. ```yaml _metadata: @@ -155,7 +155,7 @@ lt --port 8080 -s pretty-turkey-83 --print-requests socket_mode_enabled: false ``` -6. Set environment variables by navigating to your Grafana OnCall, then click **Env Variables** and set the following: +1. Set environment variables by navigating to your Grafana OnCall, then click **Env Variables** and set the following: ``` SLACK_CLIENT_OAUTH_ID = Basic Information -> App Credentials -> Client ID SLACK_CLIENT_OAUTH_SECRET = Basic Information -> App Credentials -> Client Secret @@ -163,9 +163,9 @@ lt --port 8080 -s pretty-turkey-83 --print-requests SLACK_INSTALL_RETURN_REDIRECT_HOST = << OnCall external URL >> ``` -7. From OnCall, navigate to **ChatOps**, select Slack and click **Install Slack integration**. +1. In OnCall, navigate to **ChatOps**, select Slack and click **Install Slack integration**. -8. Configure additional Slack settings as needed and your integration is ready for use. +1. Configure additional Slack settings. ## Telegram integration for Grafana OnCall OSS @@ -181,11 +181,11 @@ Review the following requirements to configure Telegram for Grafana OnCall OSS: 1. Ensure your OnCall environment is up and running. -2. Request [BotFather](https://t.me/BotFather) for a key, then add your key in `TELEGRAM_TOKEN` in your Grafana OnCall **Env Variables**. +1. Request [BotFather](https://t.me/BotFather) for a key, then add your key in `TELEGRAM_TOKEN` in your Grafana OnCall **Env Variables**. -3. Set `TELEGRAM_WEBHOOK_HOST` with your external URL for your Grafana OnCall. +1. Set `TELEGRAM_WEBHOOK_HOST` with your external URL for your Grafana OnCall. -4. From the **ChatOps** tab in Grafana OnCall, click **Telegram** and your integration is now ready for use. +1. From the **ChatOps** tab in Grafana OnCall, click **Telegram**. ## Connect Grafana Cloud to Grafana OnCall OSS From 3f8dad44677b84b96b788e019429b4c60d3cba5e Mon Sep 17 00:00:00 2001 From: alyssa wada Date: Tue, 21 Jun 2022 09:10:45 -0600 Subject: [PATCH 06/18] open source edits --- docs/sources/open-source.md | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/docs/sources/open-source.md b/docs/sources/open-source.md index ad373fd9..690969bf 100644 --- a/docs/sources/open-source.md +++ b/docs/sources/open-source.md @@ -31,19 +31,9 @@ For detailed installation instructions and additional resources, refer to the OS For more information on production environment installation, refer to the following OSS Grafana OnCall [production environment helm chart](https://github.com/grafana/oncall/helm) -## Slack integration for Grafana OnCall OSS +## Configure Slack for Grafana OnCall OSS -The Slack integration for Grafana OnCall leverages Slack API features to provide a customizable and useful integration. - -### Before you begin - -Review the following requirements to configure Slack for Grafana OnCall OSS: - -- Ensure your Grafana OnCall environment is running. -- Grafana OnCall must be externally available and provide HTTPS endpoint to establish subscription on Slack events. -- Create a new Slack App from Grafana OnCall app manifest. - -### Configure Slack for Grafana OnCall OSS +The Slack integration for Grafana OnCall leverages Slack API features to provide a customizable and useful integration. Refer to the following steps to configure the Slack integration: 1. Ensure your Grafana OnCall environment is up and running. @@ -167,17 +157,9 @@ lt --port 8080 -s pretty-turkey-83 --print-requests 8. Configure additional Slack settings as needed and your integration is ready for use. -## Telegram integration for Grafana OnCall OSS + ## Configure Telegram for Grafana OnCall OSS -The Telegram integration for Grafana OnCall is designed for collaborative team work and improved incident response. -### Before your begin - -Review the following requirements to configure Telegram for Grafana OnCall OSS: -- Ensure your Grafana OnCall environment is running. -- Grafana OnCall must be externally available and provide HTTPS endpoint to establish subscription on Telegram events. -- Create new Telegram Group and private Telegram channel for alerts. - -### Configure Telegram for Grafana OnCall OSS +The Telegram integration for Grafana OnCall is designed for collaborative team work and improved incident response. Refer to the following steps to configure the Telegram integration: 1. Ensure your OnCall environment is up and running. From 3633c6438acdbd0873f675c815c89d516620b7a9 Mon Sep 17 00:00:00 2001 From: alyssa wada Date: Tue, 21 Jun 2022 09:18:46 -0600 Subject: [PATCH 07/18] minor format edit --- docs/sources/open-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/open-source.md b/docs/sources/open-source.md index 116c3da7..bb1114b1 100644 --- a/docs/sources/open-source.md +++ b/docs/sources/open-source.md @@ -189,4 +189,4 @@ To connect to Grafana Cloud, refer to the **Cloud** page in your OSS Grafana OnC Grafana OnCall supports Twilio SMS and phone call notifications delivery. If you prefer to configure SMS and phone call notifications using Twilio, complete the following steps: 1. Set `GRAFANA_CLOUD_NOTIFICATIONS_ENABLED` as **False** to ensure the Grafana OSS <-> Cloud connector is disabled. -2. From your **OnCall** environment, select **Env Variables** and configure all variables starting with `TWILIO_`. +1. From your **OnCall** environment, select **Env Variables** and configure all variables starting with `TWILIO_`. From 99aff9f09659418ba5245032397355e485eb76c3 Mon Sep 17 00:00:00 2001 From: Yulia Shanyrova Date: Wed, 22 Jun 2022 14:09:52 +0200 Subject: [PATCH 08/18] fix to not close the collapse component --- grafana-plugin/src/containers/AlertRules/AlertRules.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grafana-plugin/src/containers/AlertRules/AlertRules.tsx b/grafana-plugin/src/containers/AlertRules/AlertRules.tsx index 512f1d9c..36b6fe52 100644 --- a/grafana-plugin/src/containers/AlertRules/AlertRules.tsx +++ b/grafana-plugin/src/containers/AlertRules/AlertRules.tsx @@ -726,7 +726,7 @@ class AlertRules extends React.Component { />
-
{this.renderChannelFilterButtons(channelFilterId, index)}
+
e.stopPropagation()}>{this.renderChannelFilterButtons(channelFilterId, index)}
); }; From e06f77389a1fe52a8b57b20e18b1a515606be187 Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Wed, 22 Jun 2022 18:11:17 +0400 Subject: [PATCH 09/18] Fix Status column in the user table (#123) * Fix Status column in the user table * Request features in users table * Remove check of features in users table * Polishing * Fix style * Inroduce hidden_fields * Fix comment --- engine/apps/api/serializers/user.py | 1 + grafana-plugin/src/models/user/user.types.ts | 1 + grafana-plugin/src/pages/users/Users.tsx | 32 +++++++++----------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/engine/apps/api/serializers/user.py b/engine/apps/api/serializers/user.py index db0db0ed..51418885 100644 --- a/engine/apps/api/serializers/user.py +++ b/engine/apps/api/serializers/user.py @@ -119,6 +119,7 @@ class UserHiddenFieldsSerializer(UserSerializer): for field in ret: if field not in self.available_for_all_roles_fields: ret[field] = "******" + ret["hidden_fields"] = True return ret diff --git a/grafana-plugin/src/models/user/user.types.ts b/grafana-plugin/src/models/user/user.types.ts index 4f1ba2ed..7bb09e0d 100644 --- a/grafana-plugin/src/models/user/user.types.ts +++ b/grafana-plugin/src/models/user/user.types.ts @@ -53,4 +53,5 @@ export interface User { status?: number; link?: string; cloud_connection_status?: number; + hidden_fields?: boolean; } diff --git a/grafana-plugin/src/pages/users/Users.tsx b/grafana-plugin/src/pages/users/Users.tsx index 87abf9cd..a8ab3c5b 100644 --- a/grafana-plugin/src/pages/users/Users.tsx +++ b/grafana-plugin/src/pages/users/Users.tsx @@ -59,7 +59,6 @@ class Users extends React.Component { store, query: { p }, } = this.props; - this.setState({ page: p ? Number(p) : 1 }, this.updateUsers); this.parseParams(); @@ -292,37 +291,34 @@ class Users extends React.Component { }; renderNote = (user: UserType) => { - const { store } = this.props; - let phone_verified; - let phone_verified_message; - if (store.hasFeature(AppFeature.CloudNotifications)) { - // If cloud notifications is enabled show message about its status, not local phone verification. + if (user.hidden_fields === true) { + return null; + } + let phone_verified = user.verified_phone_number !== null; + let phone_not_verified_message = 'Phone not verified'; + + if (user.cloud_connection_status !== null) { + phone_verified = false; switch (user.cloud_connection_status) { case 0: - phone_verified = false; - phone_verified_message = 'Cloud is not synced'; + phone_not_verified_message = 'Cloud is not synced'; break; case 1: - phone_verified = false; - phone_verified_message = 'User not matched with cloud'; + phone_not_verified_message = 'User not matched with cloud'; break; case 2: - phone_verified = false; - phone_verified_message = 'Phone number is not verified in Grafana Cloud'; + phone_not_verified_message = 'Phone number is not verified in Grafana Cloud'; break; case 3: - phone_verified = false; - phone_verified_message = 'Phone number is verified in Grafana Cloud'; + phone_verified = true; break; } - } else { - phone_verified = user.verified_phone_number; - phone_verified_message = 'Phone not verified'; } + if (!phone_verified || !user.slack_user_identity || !user.telegram_configuration) { let texts = []; if (!phone_verified) { - texts.push(phone_verified_message); + texts.push(phone_not_verified_message); } if (!user.slack_user_identity) { texts.push('Slack not verified'); From 0d12671015d6d86206b36866347283c523b1481c Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Wed, 22 Jun 2022 14:46:23 -0300 Subject: [PATCH 10/18] List all users in public users endpoint --- engine/apps/public_api/tests/test_users.py | 37 ++++++++++++++++++++++ engine/apps/public_api/views/users.py | 3 +- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/engine/apps/public_api/tests/test_users.py b/engine/apps/public_api/tests/test_users.py index 7208976c..892fbc38 100644 --- a/engine/apps/public_api/tests/test_users.py +++ b/engine/apps/public_api/tests/test_users.py @@ -3,6 +3,8 @@ from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient +from common.constants.role import Role + @pytest.fixture() def user_public_api_setup( @@ -140,3 +142,38 @@ def test_forbidden_access( response = client.get(url, format="json", HTTP_AUTHORIZATION=another_org_token) assert response.status_code == status.HTTP_404_NOT_FOUND + + +@pytest.mark.django_db +def test_get_users_list_all_role_users( + user_public_api_setup, + make_user_for_organization, +): + organization, admin, token, _, _ = user_public_api_setup + editor = make_user_for_organization(organization, role=Role.EDITOR) + viewer = make_user_for_organization(organization, role=Role.VIEWER) + + client = APIClient() + + url = reverse("api-public:users-list") + response = client.get(f"{url}?short=true", format="json", HTTP_AUTHORIZATION=token) + + expected_users = [(admin, "admin"), (editor, "editor"), (viewer, "viewer")] + expected_response = { + "count": 3, + "next": None, + "previous": None, + "results": [ + { + "id": user.public_primary_key, + "email": user.email, + "username": user.username, + "role": role, + "is_phone_number_verified": False, + } + for user, role in expected_users + ], + } + + assert response.status_code == status.HTTP_200_OK + assert response.json() == expected_response diff --git a/engine/apps/public_api/views/users.py b/engine/apps/public_api/views/users.py index 54439d6e..33415d19 100644 --- a/engine/apps/public_api/views/users.py +++ b/engine/apps/public_api/views/users.py @@ -13,7 +13,6 @@ from apps.schedules.models import OnCallSchedule from apps.user_management.models import User from common.api_helpers.mixins import RateLimitHeadersMixin, ShortSerializerMixin from common.api_helpers.paginators import HundredPageSizePaginator -from common.constants.role import Role class UserView(RateLimitHeadersMixin, ShortSerializerMixin, ReadOnlyModelViewSet): @@ -32,7 +31,7 @@ class UserView(RateLimitHeadersMixin, ShortSerializerMixin, ReadOnlyModelViewSet username = self.request.query_params.get("username") email = self.request.query_params.get("email") is_short_request = self.request.query_params.get("short", "false") == "true" - queryset = self.request.auth.organization.users.filter(role__in=[Role.ADMIN, Role.EDITOR]).distinct() + queryset = self.request.auth.organization.users.all() if username is not None: queryset = queryset.filter(username=username) From cbb616bfaafd501620ab6ddea71d1b0747360fd1 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Wed, 22 Jun 2022 14:53:03 -0300 Subject: [PATCH 11/18] Minor improvements to developer docs --- DEVELOPER.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/DEVELOPER.md b/DEVELOPER.md index 37a0a526..ec014908 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -64,7 +64,7 @@ python manage.py createsuperuser 3. Launch the backend: ```bash # Http server: -python manage.py runserver 8080 +python manage.py runserver 0.0.0.0:8080 # Worker for background tasks (run it in the parallel terminal, don't forget to export .env there) python manage.py start_celery @@ -203,11 +203,20 @@ Credentials: admin/admin ### Running tests locally +In the `engine` directory, with the `.env` vars exported and virtualenv activated + +```bash +pytest ``` -# in the engine directory, with the virtualenv activated -pytest --ds=settings.dev + +You can also install `pytest.xdist` in your env and run tests in parallel: + +```bash +pip install pytest.xdist +pytest -n4 ``` + ## IDE Specific Instructions ### PyCharm From 2afd9b841781861fc551f7f6df69652c80f8a262 Mon Sep 17 00:00:00 2001 From: Fiona Artiaga <89225282+GrafanaWriter@users.noreply.github.com> Date: Wed, 22 Jun 2022 15:04:21 -0700 Subject: [PATCH 12/18] Update maintainers.md Add technical writers to maintainers list. --- MAINTAINERS.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index bd9b78f3..8447090b 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -5,7 +5,10 @@ The following are the main/default maintainers: Some parts of the codebase have other maintainers, the package paths also include all sub-packages: -n/a +Some parts of the codebase have other maintainers: +- `docs`: + - Eve Meelan - [@Eve832](https://github.com/Eve832) ([Grafana Labs](https://grafana.com/)) + - Alyssa Wada - [@alyssawada](https://github.com/alyssawada) ([Grafana Labs](https://grafana.com/)) For the sake of brevity, not all subtrees are explicitly listed. Due to the size of this repository, the natural changes in focus of maintainers over time, From 174309a5312b1750fcd65197b510e5dd280e5c68 Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Thu, 23 Jun 2022 13:46:04 +0400 Subject: [PATCH 13/18] Optimize schedules select in escalation page (#129) * Add FastScheduleSerializer * Linting * Chnaged Gselect for RemoteSelect for notifySchedules in escalation policies Co-authored-by: Yulia Shanyrova --- engine/apps/api/serializers/schedule_base.py | 12 +++++++ engine/apps/api/views/schedule.py | 32 +++++++++++++------ .../components/Policy/EscalationPolicy.tsx | 12 ++++--- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/engine/apps/api/serializers/schedule_base.py b/engine/apps/api/serializers/schedule_base.py index b9e07a24..4cbd7641 100644 --- a/engine/apps/api/serializers/schedule_base.py +++ b/engine/apps/api/serializers/schedule_base.py @@ -3,6 +3,7 @@ from rest_framework import serializers from apps.api.serializers.user_group import UserGroupSerializer from apps.schedules.ical_utils import list_users_to_notify_from_ical +from apps.schedules.models import OnCallSchedule from apps.schedules.tasks import schedule_notify_about_empty_shifts_in_schedule, schedule_notify_about_gaps_in_schedule from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField from common.api_helpers.mixins import EagerLoadingMixin @@ -83,3 +84,14 @@ class ScheduleBaseSerializer(EagerLoadingMixin, serializers.ModelSerializer): created_schedule.check_gaps_for_next_week() schedule_notify_about_gaps_in_schedule.apply_async((created_schedule.pk,)) return created_schedule + + +class ScheduleFastSerializer(serializers.ModelSerializer): + id = serializers.CharField(read_only=True, source="public_primary_key") + + class Meta: + model = OnCallSchedule + fields = [ + "id", + "name", + ] diff --git a/engine/apps/api/views/schedule.py b/engine/apps/api/views/schedule.py index 9bc55546..d27676d4 100644 --- a/engine/apps/api/views/schedule.py +++ b/engine/apps/api/views/schedule.py @@ -17,6 +17,7 @@ from rest_framework.views import Response from rest_framework.viewsets import ModelViewSet from apps.api.permissions import MODIFY_ACTIONS, READ_ACTIONS, ActionPermission, AnyRole, IsAdmin, IsAdminOrEditor +from apps.api.serializers.schedule_base import ScheduleFastSerializer from apps.api.serializers.schedule_polymorphic import ( PolymorphicScheduleCreateSerializer, PolymorphicScheduleSerializer, @@ -31,10 +32,17 @@ from apps.slack.models import SlackChannel from apps.slack.tasks import update_slack_user_group_for_schedules from apps.user_management.organization_log_creator import OrganizationLogType, create_organization_log from common.api_helpers.exceptions import BadRequest, Conflict -from common.api_helpers.mixins import CreateSerializerMixin, PublicPrimaryKeyMixin, UpdateSerializerMixin +from common.api_helpers.mixins import ( + CreateSerializerMixin, + PublicPrimaryKeyMixin, + ShortSerializerMixin, + UpdateSerializerMixin, +) -class ScheduleView(PublicPrimaryKeyMixin, CreateSerializerMixin, UpdateSerializerMixin, ModelViewSet): +class ScheduleView( + PublicPrimaryKeyMixin, ShortSerializerMixin, CreateSerializerMixin, UpdateSerializerMixin, ModelViewSet +): authentication_classes = (PluginAuthentication,) permission_classes = (IsAuthenticated, ActionPermission) action_permissions = { @@ -56,6 +64,7 @@ class ScheduleView(PublicPrimaryKeyMixin, CreateSerializerMixin, UpdateSerialize serializer_class = PolymorphicScheduleSerializer create_serializer_class = PolymorphicScheduleCreateSerializer update_serializer_class = PolymorphicScheduleUpdateSerializer + short_serializer_class = ScheduleFastSerializer @cached_property def can_update_user_groups(self): @@ -80,19 +89,22 @@ class ScheduleView(PublicPrimaryKeyMixin, CreateSerializerMixin, UpdateSerialize return context def get_queryset(self): + is_short_request = self.request.query_params.get("short", "false") == "true" organization = self.request.auth.organization - slack_channels = SlackChannel.objects.filter( - slack_team_identity=organization.slack_team_identity, - slack_id=OuterRef("channel"), - ) queryset = OnCallSchedule.objects.filter( organization=organization, team=self.request.user.current_team, - ).annotate( - slack_channel_name=Subquery(slack_channels.values("name")[:1]), - slack_channel_pk=Subquery(slack_channels.values("public_primary_key")[:1]), ) - queryset = self.serializer_class.setup_eager_loading(queryset) + if not is_short_request: + slack_channels = SlackChannel.objects.filter( + slack_team_identity=organization.slack_team_identity, + slack_id=OuterRef("channel"), + ) + queryset = queryset.annotate( + slack_channel_name=Subquery(slack_channels.values("name")[:1]), + slack_channel_pk=Subquery(slack_channels.values("public_primary_key")[:1]), + ) + queryset = self.serializer_class.setup_eager_loading(queryset) return queryset def get_object(self): diff --git a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx index f18aeb55..1d2b5ce1 100644 --- a/grafana-plugin/src/components/Policy/EscalationPolicy.tsx +++ b/grafana-plugin/src/components/Policy/EscalationPolicy.tsx @@ -11,6 +11,7 @@ import PluginLink from 'components/PluginLink/PluginLink'; import TimeRange from 'components/TimeRange/TimeRange'; import Timeline from 'components/Timeline/Timeline'; import GSelect from 'containers/GSelect/GSelect'; +import RemoteSelect from 'containers/RemoteSelect/RemoteSelect'; import UserTooltip from 'containers/UserTooltip/UserTooltip'; import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl'; import { ActionDTO } from 'models/action'; @@ -271,14 +272,15 @@ export class EscalationPolicy extends React.Component - ); From 3cdc5592baf9273d407cc880ea07de3da1175442 Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Thu, 23 Jun 2022 14:38:11 +0400 Subject: [PATCH 14/18] Fix saving of overrides_ical_file (#138) --- engine/apps/schedules/models/on_call_schedule.py | 1 + 1 file changed, 1 insertion(+) diff --git a/engine/apps/schedules/models/on_call_schedule.py b/engine/apps/schedules/models/on_call_schedule.py index 4e7e79dd..51e7b8b8 100644 --- a/engine/apps/schedules/models/on_call_schedule.py +++ b/engine/apps/schedules/models/on_call_schedule.py @@ -283,6 +283,7 @@ class OnCallScheduleICal(OnCallSchedule): self.save(update_fields=["cached_ical_file_primary", "prev_ical_file_primary", "ical_file_error_primary"]) def _refresh_overrides_ical_file(self): + self.prev_ical_file_overrides = self.cached_ical_file_overrides if self.ical_url_overrides is not None: self.cached_ical_file_overrides, self.ical_file_error_overrides = fetch_ical_file_or_get_error( self.ical_url_overrides, From 9bdf4288a0ff4235e2f494a3754116bae36a3d98 Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Thu, 23 Jun 2022 18:17:07 +0400 Subject: [PATCH 15/18] Fix support of public users api in sync_users_with_cloud (#139) * Fix support of public API * Style fixes --- .../models/cloud_connector.py | 4 +-- engine/apps/public_api/views/users.py | 28 +++++++++++++------ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/engine/apps/oss_installation/models/cloud_connector.py b/engine/apps/oss_installation/models/cloud_connector.py index 38541bf5..fefc640e 100644 --- a/engine/apps/oss_installation/models/cloud_connector.py +++ b/engine/apps/oss_installation/models/cloud_connector.py @@ -69,7 +69,7 @@ class CloudConnector(models.Model): page = 1 while fetch_next_page: try: - url = urljoin(users_url, f"?page={page}&?short=true") + url = urljoin(users_url, f"?page={page}&short=true&roles=0&roles=1") r = requests.get(url, headers={"AUTHORIZATION": api_token}, timeout=5) if r.status_code != 200: logger.warning( @@ -115,7 +115,7 @@ class CloudConnector(models.Model): logger.warning(f"Unable to sync_user_with cloud user_id {user.id}. GRAFANA_CLOUD_ONCALL_TOKEN is not set") error_msg = "GRAFANA_CLOUD_ONCALL_TOKEN is not set" else: - url = urljoin(GRAFANA_CLOUD_ONCALL_API_URL, f"api/v1/users/?email={user.email}") + url = urljoin(GRAFANA_CLOUD_ONCALL_API_URL, f"api/v1/users/?email={user.email}&roles=0&roles=1&short=true") try: r = requests.get(url, headers={"AUTHORIZATION": api_token}, timeout=5) if r.status_code != 200: diff --git a/engine/apps/public_api/views/users.py b/engine/apps/public_api/views/users.py index 33415d19..84851042 100644 --- a/engine/apps/public_api/views/users.py +++ b/engine/apps/public_api/views/users.py @@ -1,3 +1,4 @@ +from django_filters import rest_framework as filters from rest_framework.decorators import action from rest_framework.exceptions import NotFound from rest_framework.permissions import IsAuthenticated @@ -13,6 +14,21 @@ from apps.schedules.models import OnCallSchedule from apps.user_management.models import User from common.api_helpers.mixins import RateLimitHeadersMixin, ShortSerializerMixin from common.api_helpers.paginators import HundredPageSizePaginator +from common.constants.role import Role + + +class UserFilter(filters.FilterSet): + """ + https://django-filter.readthedocs.io/en/master/guide/rest_framework.html + """ + + email = filters.CharFilter(field_name="email", lookup_expr="iexact") + roles = filters.MultipleChoiceFilter(field_name="role", choices=Role.choices()) + username = filters.CharFilter(field_name="username", lookup_expr="iexact") + + class Meta: + model = User + fields = ["email", "roles", "username"] class UserView(RateLimitHeadersMixin, ShortSerializerMixin, ReadOnlyModelViewSet): @@ -24,23 +40,17 @@ class UserView(RateLimitHeadersMixin, ShortSerializerMixin, ReadOnlyModelViewSet serializer_class = UserSerializer short_serializer_class = FastUserSerializer + filterset_class = UserFilter + filter_backends = (filters.DjangoFilterBackend,) throttle_classes = [UserThrottle] def get_queryset(self): - username = self.request.query_params.get("username") - email = self.request.query_params.get("email") is_short_request = self.request.query_params.get("short", "false") == "true" queryset = self.request.auth.organization.users.all() - - if username is not None: - queryset = queryset.filter(username=username) - - if email is not None: - queryset = queryset.filter(email=email) - if not is_short_request: queryset = self.serializer_class.setup_eager_loading(queryset) + queryset = self.filter_queryset(queryset) return queryset.order_by("id") def get_object(self): From 5dd0821f4c4c45b17416b6e2cc3bb9df5ddd6a30 Mon Sep 17 00:00:00 2001 From: Vadim Stepanov Date: Fri, 24 Jun 2022 13:50:29 +0100 Subject: [PATCH 16/18] Remove naming artifacts from personal log record messages (#143) --- .../apps/base/models/user_notification_policy_log_record.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/apps/base/models/user_notification_policy_log_record.py b/engine/apps/base/models/user_notification_policy_log_record.py index 15f86067..1182cce7 100644 --- a/engine/apps/base/models/user_notification_policy_log_record.py +++ b/engine/apps/base/models/user_notification_policy_log_record.py @@ -197,13 +197,13 @@ class UserNotificationPolicyLogRecord(models.Model): elif notification_channel is None: result += f"failed to notify {user_verbal}. Phone number is not verified" if self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_NOT_ABLE_TO_SEND_SMS: - result += f"Amixr was not able to send an SMS to {user_verbal}" + result += f"OnCall was not able to send an SMS to {user_verbal}" elif self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_NOT_ABLE_TO_CALL: - result += f"Amixr was not able to call to {user_verbal}" + result += f"OnCall was not able to call to {user_verbal}" elif ( self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_NOT_ABLE_TO_SEND_MAIL ): - result += f"Amixr was not able to send an email to {user_verbal}" + result += f"OnCall was not able to send an email to {user_verbal}" elif ( self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_POSTING_TO_SLACK_IS_DISABLED From e148d6fc8a63b50d37a11f7e7ef49a1d3c90bc1d Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Fri, 24 Jun 2022 17:31:39 +0400 Subject: [PATCH 17/18] Fix listen_for_usernotificationpolicylogrecord_model_save (#146) --- engine/apps/base/models/user_notification_policy_log_record.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/apps/base/models/user_notification_policy_log_record.py b/engine/apps/base/models/user_notification_policy_log_record.py index 1182cce7..2cfc3b0a 100644 --- a/engine/apps/base/models/user_notification_policy_log_record.py +++ b/engine/apps/base/models/user_notification_policy_log_record.py @@ -314,7 +314,8 @@ class UserNotificationPolicyLogRecord(models.Model): @receiver(post_save, sender=UserNotificationPolicyLogRecord) def listen_for_usernotificationpolicylogrecord_model_save(sender, instance, created, *args, **kwargs): - alert_group_pk = instance.alert_group.drop_cached_after_resolve_report_json() + instance.alert_group.drop_cached_after_resolve_report_json() + alert_group_pk = instance.alert_group.pk if instance.type != UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FINISHED: logger.debug( f"send_update_log_report_signal for alert_group {alert_group_pk}, " From f1c6a1a665d76e0ee43af291ad93f9f9b7b1fea1 Mon Sep 17 00:00:00 2001 From: Roman Pertl Date: Sat, 25 Jun 2022 11:11:14 +0200 Subject: [PATCH 18/18] Remove unused caddy volumes from docker compose Caddy container has been removed in https://github.com/roock/grafana-oncall/commit/bd923936575bed2a92cfbc5b7e348d9ca4ce1e3d but volumes have not been removed --- docker-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index bf44777b..1d711e11 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -171,5 +171,3 @@ services: volumes: dbdata: rabbitmqdata: - caddy_data: - caddy_config: