Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert slack org does not exist changes breaking escalate command #2057

Merged
merged 1 commit into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Fixed

- Revert #2040 breaking `/escalate` Slack command

## v1.2.32 (2023-05-30)

### Added
Expand Down
96 changes: 0 additions & 96 deletions engine/apps/slack/tests/test_interactive_api_endpoint.py

This file was deleted.

155 changes: 68 additions & 87 deletions engine/apps/slack/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
from apps.slack.slack_client import SlackClientWithErrorHandling
from apps.slack.slack_client.exceptions import SlackAPIException, SlackAPITokenException
from apps.slack.tasks import clean_slack_integration_leftovers, unpopulate_slack_user_identities
from apps.user_management.models import Organization
from common.insight_log import ChatOpsEvent, ChatOpsTypePlug, write_chatops_insight_log
from common.oncall_gateway import delete_slack_connector

Expand Down Expand Up @@ -286,19 +285,6 @@ def post(self, request):
# Open pop-up to inform user why OnCall bot doesn't work if any action was triggered
self._open_warning_window_if_needed(payload, slack_team_identity, warning_text)
return Response(status=200)
elif organization is None:
# see this GitHub issue for more context on how this situation can arise
# https://github.com/grafana/oncall-private/issues/1836
warning_text = (
"OnCall is not able to process this action because one of the following scenarios: \n"
"1. The Slack chatops integration was disconnected from the instance that the Alert Group belongs "
"to, BUT the Slack workspace is still connected to another instance as well. In this case, simply log "
"in to the OnCall web interface and re-install the Slack Integration with this workspace again.\n"
"2. (Less likely) The Grafana instance belonging to this Alert Group was deleted. In this case the Alert Group is orphaned and cannot be acted upon."
)
# Open pop-up to inform user why OnCall bot doesn't work if any action was triggered
self._open_warning_window_if_needed(payload, slack_team_identity, warning_text)
return Response(status=200)
elif not slack_user_identity.users.exists():
# Means that slack_user_identity doesn't have any connected user
# Open pop-up to inform user why OnCall bot doesn't work if any action was triggered
Expand Down Expand Up @@ -434,81 +420,76 @@ def _get_organization_from_payload(self, payload, slack_team_identity):
channel_id = None
organization = None

try:
# view submission or actions in view
if "view" in payload:
organization_id = None
private_metadata = payload["view"].get("private_metadata")
# steps with private_metadata in which we know organization before open view
if private_metadata and "organization_id" in private_metadata:
organization_id = json.loads(private_metadata).get("organization_id")
# steps with organization selection in view (e.g. slash commands)
elif SELECT_ORGANIZATION_AND_ROUTE_BLOCK_ID in payload["view"].get("state", {}).get("values", {}):
payload_values = payload["view"]["state"]["values"]
selected_value = payload_values[SELECT_ORGANIZATION_AND_ROUTE_BLOCK_ID][
SELECT_ORGANIZATION_AND_ROUTE_BLOCK_ID
]["selected_option"]["value"]
organization_id = int(selected_value.split("-")[0])
if organization_id:
organization = slack_team_identity.organizations.get(pk=organization_id)
return organization
# buttons and actions
elif payload.get("type") in [
PAYLOAD_TYPE_BLOCK_ACTIONS,
PAYLOAD_TYPE_INTERACTIVE_MESSAGE,
PAYLOAD_TYPE_MESSAGE_ACTION,
]:
# for cases when we put organization_id into action value (e.g. public suggestion)
if (
payload.get("actions")
and payload["actions"][0].get("value", {})
and "organization_id" in payload["actions"][0]["value"]
):
organization_id = int(json.loads(payload["actions"][0]["value"])["organization_id"])
organization = slack_team_identity.organizations.get(pk=organization_id)
return organization

channel_id = payload["channel"]["id"]
if "message" in payload:
message_ts = payload["message"].get("thread_ts") or payload["message"]["ts"]
# for interactive message
elif "message_ts" in payload:
message_ts = payload["message_ts"]
else:
return
# events
elif payload.get("type") == PAYLOAD_TYPE_EVENT_CALLBACK:
if "channel" in payload["event"]: # events without channel: user_change, events with subteam, etc.
channel_id = payload["event"]["channel"]

if "message" in payload["event"]:
message_ts = payload["event"]["message"].get("thread_ts") or payload["event"]["message"]["ts"]
elif "thread_ts" in payload["event"]:
message_ts = payload["event"]["thread_ts"]
else:
return

if not (message_ts and channel_id):
# view submission or actions in view
if "view" in payload:
organization_id = None
private_metadata = payload["view"].get("private_metadata")
# steps with private_metadata in which we know organization before open view
if private_metadata and "organization_id" in private_metadata:
organization_id = json.loads(private_metadata).get("organization_id")
# steps with organization selection in view (e.g. slash commands)
elif SELECT_ORGANIZATION_AND_ROUTE_BLOCK_ID in payload["view"].get("state", {}).get("values", {}):
payload_values = payload["view"]["state"]["values"]
selected_value = payload_values[SELECT_ORGANIZATION_AND_ROUTE_BLOCK_ID][
SELECT_ORGANIZATION_AND_ROUTE_BLOCK_ID
]["selected_option"]["value"]
organization_id = int(selected_value.split("-")[0])
if organization_id:
organization = slack_team_identity.organizations.get(pk=organization_id)
return organization
# buttons and actions
elif payload.get("type") in [
PAYLOAD_TYPE_BLOCK_ACTIONS,
PAYLOAD_TYPE_INTERACTIVE_MESSAGE,
PAYLOAD_TYPE_MESSAGE_ACTION,
]:
# for cases when we put organization_id into action value (e.g. public suggestion)
if (
payload.get("actions")
and payload["actions"][0].get("value", {})
and "organization_id" in payload["actions"][0]["value"]
):
organization_id = int(json.loads(payload["actions"][0]["value"])["organization_id"])
organization = slack_team_identity.organizations.get(pk=organization_id)
return organization

channel_id = payload["channel"]["id"]
if "message" in payload:
message_ts = payload["message"].get("thread_ts") or payload["message"]["ts"]
# for interactive message
elif "message_ts" in payload:
message_ts = payload["message_ts"]
else:
return

try:
slack_message = SlackMessage.objects.get(
slack_id=message_ts,
_slack_team_identity=slack_team_identity,
channel_id=channel_id,
)
except SlackMessage.DoesNotExist:
pass
# events
elif payload.get("type") == PAYLOAD_TYPE_EVENT_CALLBACK:
if "channel" in payload["event"]: # events without channel: user_change, events with subteam, etc.
channel_id = payload["event"]["channel"]

if "message" in payload["event"]:
message_ts = payload["event"]["message"].get("thread_ts") or payload["event"]["message"]["ts"]
elif "thread_ts" in payload["event"]:
message_ts = payload["event"]["thread_ts"]
else:
alert_group = slack_message.get_alert_group()
if alert_group:
organization = alert_group.channel.organization
return organization
return organization
except Organization.DoesNotExist:
# see this GitHub issue for more context on how this situation can arise
# https://github.com/grafana/oncall-private/issues/1836
return None
return

if not (message_ts and channel_id):
return

try:
slack_message = SlackMessage.objects.get(
slack_id=message_ts,
_slack_team_identity=slack_team_identity,
channel_id=channel_id,
)
except SlackMessage.DoesNotExist:
pass
else:
alert_group = slack_message.get_alert_group()
if alert_group:
organization = alert_group.channel.organization
return organization
return organization

def _open_warning_window_if_needed(self, payload, slack_team_identity, warning_text) -> None:
if payload.get("trigger_id") is not None:
Expand Down