def test_simple(self): logo_url = absolute_uri( get_asset_url("sentry", "images/sentry-email-avatar.png")) alert_rule = self.create_alert_rule() incident = self.create_incident(alert_rule=alert_rule, status=2) title = u"{}: {}".format("Resolved", alert_rule.name) assert build_incident_attachment(incident) == { "fallback": title, "title": title, "title_link": absolute_uri( reverse( "sentry-metric-alert", kwargs={ "organization_slug": incident.organization.slug, "incident_id": incident.identifier, }, )), "text": "0 events in the last 10 minutes\nFilter: level:error", "fields": [], "mrkdwn_in": ["text"], "footer_icon": logo_url, "footer": "Sentry Incident", "ts": to_timestamp(incident.date_started), "color": RESOLVED_COLOR, "actions": [], }
def run_test(self, incident, method): from sentry.integrations.pagerduty.utils import build_incident_attachment action = self.create_alert_rule_trigger_action( target_identifier=self.service.id, type=AlertRuleTriggerAction.Type.PAGERDUTY, target_type=AlertRuleTriggerAction.TargetType.SPECIFIC, integration=self.integration, ) responses.add( method=responses.POST, url="https://events.pagerduty.com/v2/enqueue/", json={}, status=202, content_type="application/json", ) handler = PagerDutyActionHandler(action, incident, self.project) metric_value = 1000 with self.tasks(): getattr(handler, method)(metric_value) data = responses.calls[0].request.body assert json.loads(data) == build_incident_attachment( action, incident, self.service.integration_key, metric_value, method)
def run_test(self, incident, method): from sentry.rules.actions.notify_event_service import build_incident_attachment action = self.create_alert_rule_trigger_action( target_identifier=self.sentry_app.id, type=AlertRuleTriggerAction.Type.SENTRY_APP, target_type=AlertRuleTriggerAction.TargetType.SENTRY_APP, sentry_app=self.sentry_app, ) responses.add( method=responses.POST, url="https://example.com/webhook", status=200, content_type="application/json", body=json.dumps({"ok": "true"}), ) handler = SentryAppActionHandler(action, incident, self.project) metric_value = 1000 with self.tasks(): getattr(handler, method)(metric_value) data = responses.calls[0].request.body assert json.dumps( build_incident_attachment(action, incident, metric_value, method)) in data
def test_build_incident_attachment(self): from sentry.integrations.pagerduty.utils import build_incident_attachment alert_rule = self.create_alert_rule() incident = self.create_incident(alert_rule=alert_rule) update_incident_status( incident, IncidentStatus.CRITICAL, status_method=IncidentStatusMethod.RULE_TRIGGERED) integration_key = "pfc73e8cb4s44d519f3d63d45b5q77g9" metric_value = 1000 data = build_incident_attachment(incident, integration_key, metric_value) assert data["routing_key"] == "pfc73e8cb4s44d519f3d63d45b5q77g9" assert data["event_action"] == "trigger" assert data["dedup_key"] == "incident_{}_{}".format( incident.organization_id, incident.identifier) assert data["payload"]["summary"] == alert_rule.name assert data["payload"]["severity"] == "critical" assert data["payload"]["source"] == six.text_type(incident.identifier) assert data["payload"]["custom_details"] == { "details": "1000 events in the last 10 minutes\nFilter: level:error" } assert data["links"][0]["text"] == "Critical: {}".format( alert_rule.name) assert data["links"][0][ "href"] == "http://testserver/organizations/baz/alerts/1/"
def test_build_incident_attachment(self): from sentry.integrations.pagerduty.utils import build_incident_attachment alert_rule = self.create_alert_rule() incident = self.create_incident(alert_rule=alert_rule) update_incident_status( incident, IncidentStatus.CRITICAL, status_method=IncidentStatusMethod.RULE_TRIGGERED) action = self.create_alert_rule_trigger_action( target_identifier=self.service.id, type=AlertRuleTriggerAction.Type.PAGERDUTY, target_type=AlertRuleTriggerAction.TargetType.SPECIFIC, integration=self.integration, ) metric_value = 1000 data = build_incident_attachment(action, incident, self.integration_key, metric_value) assert data["routing_key"] == self.integration_key assert data["event_action"] == "trigger" assert data[ "dedup_key"] == f"incident_{incident.organization_id}_{incident.identifier}" assert data["payload"]["summary"] == alert_rule.name assert data["payload"]["severity"] == "critical" assert data["payload"]["source"] == str(incident.identifier) assert data["payload"]["custom_details"] == { "details": "1000 events in the last 10 minutes\nFilter: level:error" } assert data["links"][0]["text"] == f"Critical: {alert_rule.name}" assert data["links"][0][ "href"] == "http://testserver/organizations/baz/alerts/1/"
def test_simple(self): logo_url = absolute_uri(get_asset_url("sentry", "images/sentry-email-avatar.png")) incident = self.create_incident() title = "INCIDENT: {} (#{})".format(incident.title, incident.identifier) assert build_incident_attachment(incident) == { "fallback": title, "title": title, "title_link": absolute_uri( reverse( "sentry-incident", kwargs={ "organization_slug": incident.organization.slug, "incident_id": incident.identifier, }, ) ), "text": " ", "fields": [ {"title": "Status", "value": "Open", "short": True}, {"title": "Events", "value": 0, "short": True}, {"title": "Users", "value": 0, "short": True}, ], "mrkdwn_in": ["text"], "footer_icon": logo_url, "footer": "Sentry Incident", "ts": to_timestamp(incident.date_started), "color": LEVEL_TO_COLOR["error"], "actions": [], }
def test_valid_token(self): responses.add(responses.POST, 'https://slack.com/api/chat.unfurl', json={'ok': True}) org2 = self.create_organization(name='biz') project1 = self.create_project(organization=self.org) project2 = self.create_project(organization=org2) group1 = self.create_group(project=project1) group2 = self.create_group(project=project2) incident = self.create_incident(organization=self.org, projects=[project1]) incident.update(identifier=123) resp = self.post_webhook(event_data=json.loads(LINK_SHARED_EVENT % { 'group1': group1.id, 'group2': group2.id, 'incident': incident.identifier, 'org1': self.org.slug, 'org2': org2.slug, })) assert resp.status_code == 200, resp.content data = dict(parse_qsl(responses.calls[0].request.body)) unfurls = json.loads(data['unfurls']) issue_url = 'http://testserver/organizations/%s/issues/%s/bar/' % ( self.org.slug, group1.id, ) incident_url = 'http://testserver/organizations/%s/incidents/%s/' % ( self.org.slug, incident.identifier, ) assert unfurls == { issue_url: build_group_attachment(group1), incident_url: build_incident_attachment(incident), }
def unfurl_incidents(request, integration, links: List[UnfurlableUrl]) -> UnfurledUrl: filter_query = Q() # Since we don't have real ids here, we use the org slug so that we can # make sure the identifiers correspond to the correct organization. for link in links: identifier = link.args["incident_id"] org_slug = link.args["org_slug"] filter_query |= Q(identifier=identifier, organization__slug=org_slug) results = { i.identifier: i for i in Incident.objects.filter( filter_query, # Filter by integration organization here as well to make sure that # we have permission to access these incidents. organization__in=integration.organizations.all(), ) } if not results: return {} return { link.url: build_incident_attachment( action=None, incident=results[link.args["incident_id"]], ) for link in links if link.args["incident_id"] in results }
def test_simple(self): logo_url = absolute_uri(get_asset_url('sentry', 'images/sentry-email-avatar.png')) incident = self.create_incident() title = 'INCIDENT: {} (#{})'.format(incident.title, incident.identifier) assert build_incident_attachment(incident) == { 'fallback': title, 'title': title, 'title_link': absolute_uri(reverse( 'sentry-incident', kwargs={ 'organization_slug': incident.organization.slug, 'incident_id': incident.identifier, }, )), 'text': ' ', 'fields': [ {'title': 'Status', 'value': 'Open', 'short': True}, {'title': 'Events', 'value': 0, 'short': True}, {'title': 'Users', 'value': 0, 'short': True}, ], 'mrkdwn_in': ['text'], 'footer_icon': logo_url, 'footer': 'Sentry Incident', 'ts': to_timestamp(incident.date_started), 'color': LEVEL_TO_COLOR['error'], 'actions': [], }
def test_valid_token(self): responses.add(responses.POST, "https://slack.com/api/chat.unfurl", json={"ok": True}) org2 = self.create_organization(name="biz") project1 = self.create_project(organization=self.org) project2 = self.create_project(organization=org2) min_ago = iso_format(before_now(minutes=1)) group1 = self.create_group(project=project1) group2 = self.create_group(project=project2) event = self.store_event(data={ "fingerprint": ["group3"], "timestamp": min_ago }, project_id=project1.id) group3 = event.group alert_rule = self.create_alert_rule() incident = self.create_incident(status=2, organization=self.org, projects=[project1], alert_rule=alert_rule) incident.update(identifier=123) resp = self.post_webhook(event_data=json.loads( LINK_SHARED_EVENT % { "group1": group1.id, "group2": group2.id, "group3": group3.id, "incident": incident.identifier, "org1": self.org.slug, "org2": org2.slug, "event": event.event_id, })) assert resp.status_code == 200, resp.content data = dict(parse_qsl(responses.calls[0].request.body)) unfurls = json.loads(data["unfurls"]) issue_url = "http://testserver/organizations/%s/issues/%s/bar/" % ( self.org.slug, group1.id) incident_url = "http://testserver/organizations/%s/incidents/%s/" % ( self.org.slug, incident.identifier, ) event_url = "http://testserver/organizations/%s/issues/%s/events/%s/" % ( self.org.slug, group3.id, event.event_id, ) assert unfurls == { issue_url: build_group_attachment(group1), incident_url: build_incident_attachment(incident), event_url: build_group_attachment(group3, event=event, link_to_event=True), } assert data["token"] == "xoxp-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"
def run_test(self, incident, method): from sentry.integrations.slack.utils import build_incident_attachment token = "xoxb-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx" integration = Integration.objects.create( external_id="1", provider="slack", metadata={ "access_token": token, "installation_type": "born_as_bot" }, ) integration.add_organization(self.organization, self.user) channel_id = "some_id" channel_name = "#hello" responses.add( method=responses.GET, url="https://slack.com/api/conversations.list", status=200, content_type="application/json", body=json.dumps({ "ok": "true", "channels": [{ "name": channel_name[1:], "id": channel_id }] }), ) action = self.create_alert_rule_trigger_action( target_identifier=channel_name, type=AlertRuleTriggerAction.Type.SLACK, target_type=AlertRuleTriggerAction.TargetType.SPECIFIC, integration=integration, ) responses.add( method=responses.POST, url="https://slack.com/api/chat.postMessage", status=200, content_type="application/json", body='{"ok": true}', ) handler = SlackActionHandler(action, incident, self.project) metric_value = 1000 with self.tasks(): getattr(handler, method)(metric_value) data = parse_qs(responses.calls[1].request.body) assert data["channel"] == [channel_id] assert data["token"] == [token] assert json.loads( data["attachments"][0])[0] == build_incident_attachment( action, incident, metric_value, method)
def run_test(self, incident, method): from sentry.integrations.msteams.card_builder import build_incident_attachment integration = Integration.objects.create( provider="msteams", name="Galactic Empire", external_id="D4r7h_Pl4gu315_th3_w153", metadata={ "service_url": "https://smba.trafficmanager.net/amer", "access_token": "d4rk51d3", "expires_at": int(time.time()) + 86400, }, ) integration.add_organization(self.organization, self.user) channel_id = "d_s" channel_name = "Death Star" channels = [{"id": channel_id, "name": channel_name}] responses.add( method=responses.GET, url= "https://smba.trafficmanager.net/amer/v3/teams/D4r7h_Pl4gu315_th3_w153/conversations", json={"conversations": channels}, ) action = self.create_alert_rule_trigger_action( target_identifier=channel_name, type=AlertRuleTriggerAction.Type.MSTEAMS, target_type=AlertRuleTriggerAction.TargetType.SPECIFIC, integration=integration, ) responses.add( method=responses.POST, url= "https://smba.trafficmanager.net/amer/v3/conversations/d_s/activities", status=200, json={}, ) handler = MsTeamsActionHandler(action, incident, self.project) metric_value = 1000 with self.tasks(): getattr(handler, method)(metric_value) data = json.loads(responses.calls[1].request.body) assert data["attachments"][0]["content"] == build_incident_attachment( action, incident, metric_value, method)
def test_metric_value(self): logo_url = absolute_uri( get_asset_url("sentry", "images/sentry-email-avatar.png")) alert_rule = self.create_alert_rule() incident = self.create_incident(alert_rule=alert_rule, status=2) title = f"Critical: {alert_rule.name}" # This test will use the action/method and not the incident to build status metric_value = 5000 trigger = self.create_alert_rule_trigger(alert_rule, CRITICAL_TRIGGER_LABEL, 100) action = self.create_alert_rule_trigger_action( alert_rule_trigger=trigger, triggered_for_incident=incident) incident_footer_ts = ( "<!date^{:.0f}^Sentry Incident - Started {} at {} | Sentry Incident>" .format(to_timestamp(incident.date_started), "{date_pretty}", "{time}")) # This should fail because it pulls status from `action` instead of `incident` assert build_incident_attachment( action, incident, metric_value=metric_value, method="fire" ) == { "fallback": title, "title": title, "title_link": absolute_uri( reverse( "sentry-metric-alert", kwargs={ "organization_slug": incident.organization.slug, "incident_id": incident.identifier, }, )), "text": f"{metric_value} events in the last 10 minutes\nFilter: level:error", "fields": [], "mrkdwn_in": ["text"], "footer_icon": logo_url, "footer": incident_footer_ts, "color": LEVEL_TO_COLOR["fatal"], "actions": [], }
def test_simple(self): logo_url = absolute_uri( get_asset_url("sentry", "images/sentry-email-avatar.png")) alert_rule = self.create_alert_rule() incident = self.create_incident(alert_rule=alert_rule, status=2) trigger = self.create_alert_rule_trigger(alert_rule, CRITICAL_TRIGGER_LABEL, 100) action = self.create_alert_rule_trigger_action( alert_rule_trigger=trigger, triggered_for_incident=incident) title = f"Resolved: {alert_rule.name}" incident_footer_ts = ( "<!date^{:.0f}^Sentry Incident - Started {} at {} | Sentry Incident>" .format(to_timestamp(incident.date_started), "{date_pretty}", "{time}")) assert build_incident_attachment(action, incident) == { "fallback": title, "title": title, "title_link": absolute_uri( reverse( "sentry-metric-alert", kwargs={ "organization_slug": incident.organization.slug, "incident_id": incident.identifier, }, )), "text": "0 events in the last 10 minutes\nFilter: level:error", "fields": [], "mrkdwn_in": ["text"], "footer_icon": logo_url, "footer": incident_footer_ts, "color": RESOLVED_COLOR, "actions": [], }