Coder Social home page Coder Social logo

monzo / response Goto Github PK

View Code? Open in Web Editor NEW
1.5K 31.0 160.0 1.4 MB

Monzo's real-time incident response and reporting tool ⚡️

License: MIT License

Shell 0.27% Python 48.43% JavaScript 49.53% CSS 0.47% HTML 1.30%
incident response incident-response incident-management incident-reports slack-bot

response's Introduction

PyPI PyPI - Python Version PyPI - Django Version Travis (.org) GitHub

Response ⚡

Dealing with incidents can be stressful. On top of dealing with the issue at hand, responders are often responsible for handling comms, coordinating the efforts of other engineers, and reporting what happened after the fact. Monzo built Response to help reduce the pressure and cognitive burden on engineers during an incident, and to make it easy to create information rich reports for others to learn from.


The headline post when an incident is declared

If you're interested in how we use this tool at Monzo, there's an overview in this video.


Try it out

Response is a Django app which you can include in your project. If you're just looking to give it a try, follow the instuctions for the demo app!


Adding Response to your own project

Start a new Django project, if you don't have one already:

$ django-admin startproject myincidentresponse

Install response:

$ pip install django-incident-response

In settings.py, add these lines to INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "after_response",
    "rest_framework",
    "bootstrap4",
    "response.apps.ResponseConfig",
]

Add the following to settings.py:

USE_TZ = False # if this exists elsewhere in your settings.py, just update the value

STATIC_ROOT = "static"

# Django Rest Framework
REST_FRAMEWORK = {
    "PAGE_SIZE": 100,
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
}
#

# Markdown Filter
MARKDOWN_FILTER_WHITELIST_TAGS = [
    "a", "p", "code", "h1", "h2", "ul", "li", "strong", "em", "img",
]

MARKDOWN_FILTER_WHITELIST_ATTRIBUTES = ["src", "style"]

MARKDOWN_FILTER_WHITELIST_STYLES = [
    "width", "height", "border-color", "background-color", "white-space",
    "vertical-align", "text-align", "border-style", "border-width", "float",
    "margin", "margin-bottom", "margin-left", "margin-right", "margin-top",
]

RESPONSE_LOGIN_REQUIRED = True

In urls.py, add the following to urlpatterns (you may also need to import include):

urlpatterns = [
    ...
    path('slack/', include('response.slack.urls')),
    path('core/', include('response.core.urls')),
    path('', include('response.ui.urls')),
]

Completing the setup and config with Slack

1. Create a Slack App

Follow these instructions to create a new Slack App.

2. Update your settings.py

Environment Variable Descriptions
SLACK_TOKEN Response needs an OAuth access token to use the Slack API.

Copy the Bot Token that starts xoxb-... from the OAuth & Permissions section of your Slack App and use it to set the SLACK_TOKEN variable.
SITE_URL Response needs to know where it is running in order to create links to the UI in Slack. Whilst running locally, you might want this set to something like http://localhost:8000.
SLACK_SIGNING_SECRET Response uses the Slack signing secret to restrict access to public endpoints.

Copy the Signing secret from the Basic Information page and use it to set the SIGNING SECRET variable.
INCIDENT_CHANNEL_ID When an incident is declared, a 'headline' post is sent to a central channel.

See the demo app settings for an example of how to get the incident channel ID from the Slack API.
INCIDENT_BOT_ID We want to invite the Bot to all Incident Channels, so need to know its ID.

See the demo app settings for an example of how to get the bot ID from the Slack API.
SLACK_CLIENT Response needs a shared global instance of a Slack Client to talk to the Slack API. Typically this does not require any additional configuration.
from response.slack.client import SlackClient
SLACK_CLIENT = SlackClient(SLACK_TOKEN)

3. Running the server

Before you can complete the Slack app setup, you need to have the app running somewhere that's accesible to to the internet. That means either deploying your Django project somewhere (see here or running it locally and exposing with something like ngrok.

For simplicity, we'll assume you're developing using ngrok.

First make sure your DB is fully migrated and up-to-date:

python3 manage.py migrate

Next, run the Django development server:

python3 manage.py runserver 0.0.0.0:8000

Finally, run ngrok:

ngrok http 8000

Make note of the ngrok url as you'll need it in the following section as the public-url.

4. Complete the Slack App Setup

Head back to the Slack web UI and complete the configuration of your app, as described here.

5. Test it's working!

In Slack, start an incident with /incident Something's happened. You should see a post in your incidents channel!

  • Visit the incident doc by clicking the Doc link.
  • Create a comms channel by clicking the button.
  • In the comms channel check out the @incident commands. You can find the ones available by entering @incident help.

response's People

Contributors

0xflotus avatar adamlphillips avatar alinbalutoiu avatar andrew-demb avatar ashleypoole avatar braderz avatar browniebroke avatar danpalmer avatar dependabot[bot] avatar dgzlopes avatar diederich avatar evnsio avatar fcvarela avatar jhutchings1 avatar kjgorman avatar lucasbode avatar marcosnils avatar mattrco avatar milesbxf avatar miraldesai avatar sjdweb avatar sophiekoonin avatar timja avatar zakhenry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

response's Issues

Error "Is the server running locally and accepting connection"

Hi,
I am just trying to setup response app on Local Laptop. Getting these error logs.

[INFO] Waiting for DB
response    | [INFO] Migrating database
postgres    | 2019-07-22 11:29:09.675 UTC [29] LOG:  incomplete startup packet
response    | Traceback (most recent call last):
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
response    |     self.connect()
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 195, in connect
response    |     self.connection = self.get_new_connection(conn_params)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
response    |     connection = Database.connect(**conn_params)
response    |   File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 126, in connect
response    |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
response    | psycopg2.OperationalError: could not connect to server: No such file or directory
response    | 	Is the server running locally and accepting
response    | 	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

Possible to set a channel name that's too long

I believe it's currently possible to set a channel name with rename that is too long to fit in the database table.

Recommendations of fixes:

  1. Convert to TextField, on Postgres at least there's essentially no performance benefit of using a CharField with a cap over a TextField if you don't want to cap the column size.
  2. Save to the database before making the Slack API calls. This way if the database save fails, Slack isn't modified, but if the API calls fail the database changes will roll back anyway.

Usage without ngrok

Is this just a case of removing these lines and setting up a reverse proxy on the machine to point at port 8000 on the response container?

ngrok:
image: gtriggiano/ngrok-tunnel
container_name: ngrok
environment:
TARGET_HOST: "response"
TARGET_PORT: 8000
ports:
- "4040:4040"

Rendering Changes to Reporter or Incident Lead

Has anyone encounters the attached issue when updating the Reporter or Incident Lead fields? The only way I can get them to display the usernames correctly is by doing a full page refresh(cmd + R).

image

TBF this seems like a Slack issue but I'm curious to see if theres a workaround. Our organisation recently migrated to Enterprise Slack which required us to upgrade our Slack clients to the latest version.

Question: Action Items

In the demo video, I saw action items was an option but I don't think it's in the public code base. Is this something that will be made available at a later date @evnsio?

Edit incident via GUI

It is shown in the video that is posted in the README that you can login/edit the incident via the GUI.

But when I run the demo application there is no way to get to this state. Is the demo app not yet updated with these features?

Incident Reports not showing at incident channel

I'm exploring this package and followed every step in the document. I got the app running and setup it up for Slack.
I tried to send a report using the /incident command, modal pop up and I input the test data on it. But the issue is that the report data does not publish to the incident channel I defined via the INCIDENT_CHANNEL_ID variable. I also expect that the data would be saved to the database defined at the settings.py, but its not.

I got no error while doing the test, so I kinda lost on how to solve the issue.

Additional details:

  • django version 2.2.15
  • django-incident-response version 0.4.0
  • python version 3.8.1
  • psycopg2-binary version 2.8.5

I also tried this using python 3.7.

[Suggestion] - Try to avoid fault releases?

@mattrco I'm aware that you're trying to do faster releases so the project doesn't stale, but for us, consumers it creates a lot of overhead to keep up. Specially if you're finding regressions and cutting sometimes 2 o 3 releases in a day. If you see some other open source projects, that's not the case.

Have you considered publishing the release after testing the system in your platform for some time? Otherwise, I find it super difficult for response users to keep up.

Feature. DB parameters with env vars

First of all want to say thank you for such wonderful tool. Its really awesome tool to manage incidents.

Small feature request.
Want to setup you tool to AWS and want to use RDS. Can you please add DB_HOST, DB_PORT, DB_USER and DB_PASSWORD as env parameter?

'channels.invite': user_not_found when creating new Comms Channel

When I create new Comms Channel I am getting following error in logs:

ERROR:response.slack.action_handlers:Error calling Slack API endpoint 'channels.invite': user_not_found

Also, the only user automatically added in that channel is myself (reporter). Not sure if that is related to this error.

Should the bot user also be automatically added to channel?

PS. Thanks for open-sourcing this great tool 🚀

Add back Statuspage and PagerDuty integrations

As in #116, we removed a few things from the 0.1.1 release (PagerDuty, Statuspage), as they didn't fit very well with the new code structure.

We also now think hardcoding them in is the wrong approach - it isn't really sustainable to have an optional settings section for each, when only a subset of users might use each bit.

Instead the new approach we're thinking of taking is creating a recipes directory, which would have subdirectories with Python files that people can simply drop into their own projects to use.

Alternatives we've considered:

Some kind of plugin system
Publishing integrations as separate importable Python/Django apps that people can install with pip

We think both of these are a bit too heavyweight - we'd like it to be as easy as possible both to create new integrations, and for people to install them. Both of these add friction to that, whereas copying + pasting some Python isn't too bad. We can reevaluate later on if this isn't the case.

It also prevents people from making their own customisations pretty easily.

TypeError: 'NoneType' object is not subscriptable

Untitled 1.docx

ATTACH WHOLE ERROR AND MY SCRIPT DOCUMENT WITH THIS

Hello,
I am trying to display form fields in report but following error occur.
Error:​
odoo.addons.base.ir.ir_qweb.qweb.QWebException: 'NoneType' object is not subscriptable
Traceback (most recent call last):
File "/usr/local/sampada/eclipse-workspace/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 343, in _compiled_fn
return compiled(self, append, new, options, log)
File "", line 1, in template_1018_120
File "", line 2, in body_call_content_119
File "", line 3, in body_call_content_118
TypeError: 'NoneType' object is not subscriptable

Feature contribution

I'd like to submit a pull request but don't have permission to push my branch. Are you open to contributions? We're using response at my work and have a few additional features in mind

Feature Request: Package as Django "app" for reusability

One of the nice features of this project is the ability to create custom interactions to power team processes.

Problem

Unfortunately to do this, users must essentially fork the codebase, add new actions, and then keep their branch up to date with master here. This isn't ideal for several reasons:

  • It's not obvious when new features/fixes/security releases are available upstream
  • It's not easy to update to only particular published versions (tags?)
  • Merging changes, particularly those to do with the infrastructure stuff here (Dockerfiles, etc) may be tricky.

Solution

I propose that a good solution for this would be to make response a Python package that provides a Django app.

What would this look like?

  • The existing apps: core, pagerduty, slack, and ui would be moved into the response app.
  • The response app would be decoupled from the Django installation currently there – removing manage.py, changing how the settings work, etc.
  • A new demo site would be created, that adds response to its INSTALLED_APPS, and perhaps implements one additional command to demonstrate how the extension would work.
  • The Docker setup provided would be updated to launch the demo site.
  • The response package would be published to PyPY, ideally with a nice CI setup in this repo for testing and publishing new versions.

This has the benefits of:

  • Pending updates are now just out of date Python packages, and we can use tooling such as Dependabot/piprot to detect, or the GitHub vulnerability alerts.
  • Updating to a new version is as simple as bumping the version requirements in your requirements.in or equivalent file, again utilising existing Python tooling such as pip-tools, pipenv, etc.
  • Merging changes is now much easier, and only becomes an issue when the public API of the response package changes (which can be tested for) rather than happening on conflicting file diffs.
  • Including custom infrastructure/deployment tooling in the repo is easier as it's not co-existing with the demo tooling provided here.

I'd appreciate any feedback or discussion on the alternatives to this approach – I'm sure there are other good options here.

Error on incident creation

Any thoughts on the below?

response    | [04/May/2019 07:55:08] "POST /slack/slash_command HTTP/1.1" 500 161449
response    | Internal Server Error: /slack/slash_command
response    | Traceback (most recent call last):
response    |   File "/app/slack/signals.py", line 21, in update_headline_after_incident_save
response    |     incident=instance
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_meth
od
response    |     return getattr(self.get_queryset(), name)(*args, **kwargs)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 399, in get
response    |     self.model._meta.object_name
response    | slack.models.headline_post.HeadlinePost.DoesNotExist: HeadlinePost matching query does not exist.
response    | 
response    | During handling of the above exception, another exception occurred:
response    | 
response    | Traceback (most recent call last):
response    |   File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response    |     response = get_response(request)
response    |   File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_respo
nse
response    |     response = self.process_exception_by_middleware(e, request)
response    |   File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 124, in _get_respo
nse
response    |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
response    |   File "/usr/local/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_
view
response    |     return view_func(*args, **kwargs)
response    |   File "/app/slack/authentication.py", line 34, in wrapper
response    |     return f(*args, **kwargs)
response    |   File "/app/slack/views.py", line 40, in slash_command

Code formatting/linting

I've been playing around with the codebase and implemented a few changes. As a newcomer to the codebase it's a little tricky to understand what the expectation of code formatting/style is.

What do the maintainers think of implementing tools such as Black for code formatting, isort for import sorting, and/or flake8 for linting? In my experience these tools make it clearer what's expected of contributors, aid readability for all, can catch bugs with some of the more interesting flake8 plugins, and can make code review more about architecture/design than style.

If the maintainers are interested in this I'm happy to have a stab at the config/implementation of this in CI, at least to start a discussion over the specifics.

Static files not being served when in PROD mode

Since the change to disable debug in PROD in #40 (rightly so!), static files are no longer being served up and producing "not found" messages for requests to the those assets including CSS, etc, when trying to view incidents in the Response web interface.

AttributeError: 'Settings' object has no attribute 'SLACK_CLIENT'

I installed the response app using pip. After attempting to use the slash command to create an incident, I received the following error. Could anyone provide some guidance on how to address it?:

AttributeError: 'Settings' object has no attribute 'SLACK_CLIENT'

Error Occured

Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

What is the 'action' command supposed to do?

A more detailed description of the @incident commands would be really useful 🙏 I haven't been able to figure out what @incident action [action_command] is supposed to achieve 🤔
image

Thanks 🌻

Add example of adding handlers/commands to demo app

Could an example of how to add additional handlers/commands be added to the demo app so consumers of the new architecture (as a package) know how they can add their own items that aren't core to the Response package?

More of a question, as an side to this, would consumers be able to override certainly handlers/actions? For example, at the moment we have a custom channel name convention for incidents -- instead of an incrementing number as the default channel name, we switched to date time to work around the issue in a development environment where the channels already existed.

Backup of odoo database

i want to take backup of odoo database using shell command and crontab please guide step by step i am new here

Feature Request: Ability to close incident from channel

Requesting feature to be able to close an incident from within the channel. I.e @incident close.

This would help as then the incident lead or engineers wouldn't have to switch back to the incidents channel in order to close the incident.

Error calling Slack API endpoint 'channels.list': method_deprecated

Have you seen this error? Mirrored the demo app, double checked the environment variables and Slack app configuration.

response    | Traceback (most recent call last):
response    |   File "manage.py", line 21, in <module>
response    |     main()
response    |   File "manage.py", line 17, in main
response    |     execute_from_command_line(sys.argv)
response    |   File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
response    |     utility.execute()
response    |   File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 325, in execute
response    |     settings.INSTALLED_APPS
response    |   File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 79, in __getattr__
response    |     self._setup(name)
response    |   File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 66, in _setup
response    |     self._wrapped = Settings(settings_module)
response    |   File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 157, in __init__
response    |     mod = importlib.import_module(self.SETTINGS_MODULE)
response    |   File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
response    |     return _bootstrap._gcd_import(name[level:], package, level)
response    |   File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
response    |   File "<frozen importlib._bootstrap>", line 983, in _find_and_load
response    |   File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
response    |   File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
response    |   File "<frozen importlib._bootstrap_external>", line 728, in exec_module
response    |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
response    |   File "/app/resp/settings/dev.py", line 59, in <module>
response    |     INCIDENT_CHANNEL_NAME
response    |   File "/usr/local/lib/python3.7/site-packages/response/slack/client.py", line 100, in get_channel_id
response    |     cursor=next_cursor,
response    |   File "/usr/local/lib/python3.7/site-packages/response/slack/client.py", line 61, in api_call
response    |     slack_error=error,
response    | response.slack.client.SlackError: Error calling Slack API endpoint 'channels.list': method_deprecated

Building features on top of demo application

Hello,

I am trying to leverage the packaged version, and adding additional functionality per this documentation: https://github.com/monzo/response/blob/master/docs/development.md

In manage.py I've added:
import ui.keyword_handlers

I've created a new file called keyword_handlers.py:

import json
import re

from response.core.models.incident import Incident
from response.slack.models import HeadlinePost, CommsChannel, UserStats, PinnedMessage
from response.slack.decorators import slack_event, handle_incident_command, handle_keywords, keyword_handler

@keyword_handler(['status page', 'statuspage'])
def status_page_notification(comms_channel: CommsChannel, user: str, text: str, ts: str):
    comms_channel.post_in_channel(f"ℹ️ You mentioned the Status Page - <{settings.STATUS_PAGE_RUNBOOK}|here's the runbook> on how to put it up.")

This isn't working though. How can I add this additional functionality to the packaged version?

Thank you.

Helm chart for Kubernetes

Hello,

First of all thanks for open sourcing this great tool, I really liked the concept behind this.
I just wanted to open this issue with regards to having a helm chart that we can install in Kubernetes. I can for sure do that and open source it in the official helm repository if you don't mind.
The only requirement for this to happen is that we need most of the configurations as env vars, including the database, like stated in this issue #19 (I can also send a PR for this if you don't mind).

Maybe there would be other people interested in this.

Thanks lot!

Possible to add a notification with a name that's too long

It's currently possible to create a notification handler with a function name too long to fit in the key column in the notifications database table.

Recommendations of fixes, either:

  • Convert to TextField, on Postgres at least there's essentially no performance benefit of using a CharField with a cap over a TextField if you don't want to cap the column size.
  • Validate at registration time of the notification handler that the function name is short enough to fit in the database.

I think the first option is a better option, as writing the name as Python source code will naturally limit it to reasonable lengths, at which using a TextField will have essentially the same performance.

TypeError: 'NoneType' object is not subscriptable

Hello,
I am trying to display form fields in report but following error occur.
Error:​
odoo.addons.base.ir.ir_qweb.qweb.QWebException: 'NoneType' object is not subscriptable
Traceback (most recent call last):
File "/usr/local/sampada/eclipse-workspace/odoo11/odoo/addons/base/ir/ir_qweb/qweb.py", line 343, in _compiled_fn
return compiled(self, append, new, options, log)
File "", line 1, in template_1018_120
File "", line 2, in body_call_content_119
File "", line 3, in body_call_content_118
TypeError: 'NoneType' object is not subscriptable

Error to render compiling AST
TypeError: 'NoneType' object is not subscriptable
Template: 1018
Path: /templates/t/t/t/div/t[1]
Node: From Date:
.py file
from odoo import models, fields, api

class DataForReport(models.AbstractModel):

_name = 'report.survey_client.pl_report_template'#for report name must be 'report.module_name.template_id_of_report'

@api.multi
def get_Form_data(self, docid, data):
model_data = data['form']
return self.report_calculations(model_data)

@api.model
def report_calculations(self,data):

from_date = data['from_date']
to_date = data['to_date']
product_id = data['product_id']

template file:

Product Profit Loss

From Date:
To Date:
Product:

Report File

I have try all solution from internet but same error will occur.any  Please help.

Make Demo Work

I set up the Demo. Trying to create an incident, I get these errors:

response    |  ERROR - signals    - 'Critical'
response    | Traceback (most recent call last):
response    |   File "/app/slack/signals.py", line 21, in update_headline_after_incident_save
response    |     incident=instance
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
response    |     return getattr(self.get_queryset(), name)(*args, **kwargs)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 408, in get
response    |     self.model._meta.object_name
response    | slack.models.headline_post.HeadlinePost.DoesNotExist: HeadlinePost matching query does not exist.

and

...(more traceback ommitted)...
response    |     msg.add_block(Section(block_id="severity", text=Text(f"{self.incident.severity_emoji()} Severity: {severity_text}")))
response    |   File "/app/core/models/incident.py", line 88, in severity_emoji
response    |     }[self.severity]
response    | KeyError: 'Critical'

I tried logging into the Web UI (...ngrok.../admin as admin/admin) which although not-documented, did work. Still, just poking around the UI a little bit I ran out of ngrok API calls. So I really can't fix this myself in a demo mode.

Thanks for what's here. Looks pretty promising!

ERROR with external users

Hello @evnsio I found strange bug after you added external user IDs.

def get_user_profile(user_id):
    if not user_id:
        return None

    response = slack_client.api_call(
        "users.info",
        user=user_id
    )

    if not response.get("ok", False):
        raise SlackError('Failed to get user profile : {}'.format(response['error']))

    return {
        'id': user_id,
        'name': response['user']['name'],
        'fullname': response['user']['profile']['real_name'],
    }

user=user_id - should be Slack user ID in such format W1234567890 according to this one https://api.slack.com/methods/users.info
But I have an error on UI /incident/<incident-id> endpoint and I see that we put not an ID but username to the function.
Screen Shot 2019-07-03 at 12 45 26 PM

Rate limiting issues with users_list call

We're seeing issues starting up services due to rate limiting by slack on the users listing calls.

The current retry behaviour is fairly aggressive and retries 10 times with an initial delay of 0.2 seconds.

Slack send a Retry-After header when rate-limiting and suggest their rate limiting is minutely, but that header is not accessible using the api_call method on the slackclient library (at least in v1, I haven't checked v2).

Ideally this would respect that header and retry after a minute or so.

Logs

On startup:

2020-11-19T13:38:46 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.20s (attempt 1 of 10)
2020-11-19T13:38:46 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.20s (attempt 1 of 10)
2020-11-19T13:38:46 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.40s (attempt 2 of 10)
2020-11-19T13:38:46 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.40s (attempt 2 of 10)
2020-11-19T13:38:47 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.60s (attempt 3 of 10)
2020-11-19T13:38:47 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.60s (attempt 3 of 10)
2020-11-19T13:38:48 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.80s (attempt 4 of 10)
2020-11-19T13:38:48 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 0.80s (attempt 4 of 10)
2020-11-19T13:38:49 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.00s (attempt 5 of 10)
2020-11-19T13:38:50 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.00s (attempt 5 of 10)
2020-11-19T13:38:50 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.20s (attempt 6 of 10)
2020-11-19T13:38:51 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.20s (attempt 6 of 10)
2020-11-19T13:38:51 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.40s (attempt 7 of 10)
2020-11-19T13:38:52 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.40s (attempt 7 of 10)
2020-11-19T13:38:53 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.60s (attempt 8 of 10)
2020-11-19T13:38:55 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 1.80s (attempt 9 of 10)
2020-11-19T13:38:57 - default/backend/050d686b89ce41e98c5aeac3e42fea29 - WARNING:root:Retrying request to users.list after error ratelimited. Backing off 2.00s (attempt 10 of 10)

During this time it seems the server is not available, which with large backoffs also result in our healthcheck killing the starting service after some timeout.

Close vs Resolve UI text

From the headline post, "resolve" is used for the button text but from within the incident the command is @incident close. Do we need to standardise on the language used or are these two events and maybe a resolve item should be added as an incident command?

2019-07-07 10_39_45-Slack - AshleyPoole

2019-07-07 10_39_24-Slack - AshleyPoole

KeyError: 'ts'

Hi,

I am trying to create an incident and I am receiving:

response    | [26/May/2019 19:52:02] "POST /slack/action HTTP/1.1" 200 0
response    |  ERROR - signals    - 'ts'
response    | Traceback (most recent call last):
response    |   File "/app/slack/signals.py", line 21, in update_headline_after_incident_save
response    |     incident=instance
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
response    |     return getattr(self.get_queryset(), name)(*args, **kwargs)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 399, in get
response    |     self.model._meta.object_name
response    | slack.models.headline_post.HeadlinePost.DoesNotExist: HeadlinePost matching query does not exist.
response    |
response    | During handling of the above exception, another exception occurred:
response    |
response    | Traceback (most recent call last):
response    |   File "/usr/local/lib/python3.7/site-packages/after_response/signals.py", line 19, in run
response    |     func(*args, **kwargs)
response    |   File "/app/slack/decorators/dialog_handler.py", line 30, in handle_dialog
response    |     callback(user_id, channel_id, submission, response_url, state)
response    |   File "/app/slack/dialog_handlers.py", line 31, in report_incident
response    |     severity=severity,
response    |   File "/app/core/models/incident.py", line 15, in create_incident
response    |     severity=severity,
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
response    |     return getattr(self.get_queryset(), name)(*args, **kwargs)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 413, in create
response    |     obj.save(force_insert=True, using=self.db)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 718, in save
response    |     force_update=force_update, update_fields=update_fields)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 758, in save_base
response    |     update_fields=update_fields, raw=raw, using=using,
response    |   File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in send
response    |     for receiver in self._live_receivers(sender)
response    |   File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in <listcomp>
response    |     for receiver in self._live_receivers(sender)
response    |   File "/app/slack/signals.py", line 27, in update_headline_after_incident_save
response    |     incident=instance
response    |   File "/app/slack/models/headline_post.py", line 16, in create_headline_post
response    |     incident=incident,
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
response    |     return getattr(self.get_queryset(), name)(*args, **kwargs)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 413, in create
response    |     obj.save(force_insert=True, using=self.db)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 718, in save
response    |     force_update=force_update, update_fields=update_fields)
response    |   File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 758, in save_base
response    |     update_fields=update_fields, raw=raw, using=using,
response    |   File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in send
response    |     for receiver in self._live_receivers(sender)
response    |   File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in <listcomp>
response    |     for receiver in self._live_receivers(sender)
response    |   File "/app/slack/signals.py", line 37, in update_headline_after_save
response    |     instance.update_in_slack()
response    |   File "/app/slack/models/headline_post.py", line 79, in update_in_slack
response    |     self.message_ts = response['ts']
response    | KeyError: 'ts'

Any clue?

Ngrok session time out

Need to sign up to ngrok and get a authentication token in order to extend the ngrok sessions past 7 hours.

Anyway to add the authentication token into this?

Thanks.

Improvements in slack integration

Hey there, we've started to use response very recently as a PoC to handle our incident response process internally. We were looking for a solution that integrates well with slack as our company is mostly distributed and we'd like to use a tool that provides flexibility and visibility during an incident and response seemed like a best fit for this purpose.
After trying response for a few days we came across a couple of bumps that we thought would have been covered given that the purpose of the tool is to coordinate and document incidents mostly that happens through slack. Here's the list that one of my colleagues (/cc @matheuss) pointed out that I also agree.

  1. It doesn't pick images when pinning a message. This happens usually when sharing a link that contains some sort of image (like a metrics graph) that slack nicely renders.
  2. it doesn't show the date in the timeline, just the time, so multi-day incidents are confusing. This should be easily fixable
  3. It'd be nice if @incident commands could be /slash commands instead as the latter ones show better contextual hints on how to use them.
  4. If action items or timeline events get edited in slack they won't get updated in response
  5. Same as above but for message deletion
  6. Action items don't translate group names
    image
  7. It'd be nice if each timeline event and action item could be linked through the URL to the original slack message. There's usually some very useful contextual information around a message that gets lost in response that i'd be nice to have.

We believe the tool has great potential as we haven't found anything similar in the OS space that provides a good out of the box integration with slack. We just wanted to point out what hurt us the most and if you have any ideas / opinions about the items described above. Keep up the awesome job!

Handlers for Incident lifecycle events

In addition to the slack event handlers provided by response, it would be great to take actions on the opening, closing or comms channel creation for an incident.

These are the sorts of things we'd like to be able to do.

  • Add a link to our runbooks as the first message in the incident channel.
  • Ask incident leads to organise a 5-whys at the end of the incident.
  • Alert #general with a quick summary when impacts are set/changed.

Currently, I don't believe (although happy to be corrected!) that there's a good place to put these. I'm sure something could be hacked together with the cron, but it would be nice to have a set of APIs to handle these.

Here's roughly what I think it could look like:

@incident_closed
def five_whys_reminder(incident: Incident) -> None:
    channel = incident.comms_channel()
    if channel is None:
        return
    channel.post_message("Please organise a 5-Whys")

If this feature would be a good addition I'm happy to have a stab at the first pass at some point, but it would be great to get some feedback on the idea.

Security: No login required

Currently response does not enforce login in the UI views or the API resources. This goes somewhat against the Django convention of being secure and safe by default.

It's possible that Monzo are deploying this internally behind a SSO proxy service, but for many users this might be prohibitively costly to set up.

I'm not sure what the right form of authentication is here. My recommendation is that response implements a response_login_required decorator, that extends the Django provided login_required decorator but can optionally disable it based on a configuration option. This option would be on by default, but disabling it provides a quick upgrade path for those installations that can be entirely unauthenticated.

This decorator would be applied to all URLs managed by response and Django Rest Framework, except for those used in the Slack integration.

Regarding Access

Hello Sir,

i remove rights of Inventory>>Transfer Save/Edit to Inventory Operator user who is only view Transfer. On main Screen Create/Edit button is not showing but if i click on any Transfer under list of that Validate/Print/Cancel buttons showing and if i click on that buttons attached error occurred.
Screenshot from 2019-09-03 14-25-01

attached error message showing on click for Validate/Print/Cancel

I need to only view Transfer to Inventory Operator . if i give full access of this program operator not able to view Validate/Print button.

Duplicate messages

Hi,

I'm seeing a strange issue whereby messages are being processed by Response multiple times.

For example, when closing an incident, it successfully closes the incident, they very quickly after also get a message about it already being closed -- which appears a few times actually, but spaced out by a minute or so.

The same duplicate behaviour happens with the @incident help command as well. Over the course of a minute, you get three help replies back.

Not sure if this is something I'm doing wrong, but as a test, I re-installed the bot within Slack to get a new token to ensure it wasn't an issue of multiple instances of Response processing the same message. Any ideas?

[Q] Is there an "official" docker image?

As title says, is there an official docker image you're using in your prod servers to spawn response? Looking forward to use it in our infra and I was wondering if I could get a curated version somewhere or if I need to push it to our own registry.

Thx!

Several things were removed in 0.1.1 without notice

Just downloaded and install the latest version of response and noticed that several things like workflows, pagerduty and statuspage are missing. After re-checking the latest release-notes (https://github.com/monzo/response/releases/tag/release-0.1.1) and not seeing anything about this I found this commit that refactors this functionality 81e389e

I guess the missing pieces here are:

  • Update the release to state that those features were removed
  • Create an issue to discuss about how this would be implemented so others can contribute? It's sad to see those features going all of the sudden. Wish the transition was smoother without actually having to lose them at all 😢

Odoo 11 Error

Hello

Thanks for previous helps, Today i am running odoo version 10 on ubuntu 19.04. this odoo version on eclipse with python version 2.7 but following error will occur.

File "/media/super/0c228924-96bf-4782-9b1e-673957fef194/sampada/eclipse-workspace/odoo10/odoo/modules/graph.py", line 13, in

import odoo.osv as osv

File "/media/super/0c228924-96bf-4782-9b1e-673957fef194/sampada/eclipse-workspace/odoo10/odoo/osv/init.py", line 4, in

import osv

File "/media/super/0c228924-96bf-4782-9b1e-673957fef194/sampada/eclipse-workspace/odoo10/odoo/osv/osv.py", line 4, in

from ..exceptions import except_orm

File "/media/super/0c228924-96bf-4782-9b1e-673957fef194/sampada/eclipse-workspace/odoo10/odoo/exceptions.py", line 15, in

from tools.func import frame_codeinfo

File "/media/super/0c228924-96bf-4782-9b1e-673957fef194/sampada/eclipse-workspace/odoo10/odoo/tools/init.py", line 8, in

from misc import *

File "/media/super/0c228924-96bf-4782-9b1e-673957fef194/sampada/eclipse-workspace/odoo10/odoo/tools/misc.py", line 23, in

import werkzeug.utils

ImportError: No module named werkzeug.utils

Can You please help me out.Thanks in Advance.

MySQL and timelines

Hi,

Is it possible to do some if/else magic around the JSONField timeline option that has just been added. As it currently stands I have to patch in django_mysql to get it to talk to MySQL.

I've included django_mysql, and replaced a few import lines like this:

#import django.contrib.postgres.fields.jsonb
from django_mysql.models import JSONField

I have nothing against postgres, I just wanted to shove this lot into the shared mysql instance I have running in gcp. It doesn't really make sense to create a total new postgres instance for it.

Cheers
Steve

Documentation neglects certain configurable items

Firstly, it looks great, and it's awesome you're open sourcing this. 👍

Few 'secure by default' requests though.
The docs don't mention that the django url sits off the response url under admin and by default the user + pass are both admin and that should really be locked down leaving only the slack url open (

This section looks like it should be changed per-deployment (secret reset / debug flicked off etc)

SECRET_KEY = 'c+*z3&f$!v@am35()o57_l885=t$2vlw*w#*jusz0qiyi#h_iz'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["*"]

If I manage to get it running I'd be happy to do a PR with some extra setup details.

I hadn't realised the repo was only 15 days old

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.