1
+ from __future__ import annotations
2
+
1
3
from collections import defaultdict
4
+ from typing import Any , DefaultDict , List , Mapping
2
5
3
6
from rest_framework import status
4
7
from rest_framework .request import Request
9
12
from sentry .api .base import region_silo_endpoint
10
13
from sentry .api .bases .organization import OrganizationEndpoint
11
14
from sentry .api .exceptions import ResourceDoesNotExist
12
- from sentry .constants import SentryAppStatus
13
15
from sentry .incidents .logic import (
14
16
get_available_action_integrations_for_org ,
15
17
get_opsgenie_teams ,
16
18
get_pagerduty_services ,
17
19
)
18
20
from sentry .incidents .models import AlertRuleTriggerAction
19
21
from sentry .incidents .serializers import ACTION_TARGET_TYPE_TO_STRING
20
- from sentry .models .integrations .sentry_app_installation import SentryAppInstallation
22
+ from sentry .models .organization import Organization
23
+ from sentry .services .hybrid_cloud .app import RpcSentryAppInstallation , app_service
24
+ from sentry .services .hybrid_cloud .integration import RpcIntegration
21
25
22
26
23
27
def build_action_response (
24
- registered_type , integration = None , organization = None , sentry_app_installation = None
25
- ):
28
+ registered_type ,
29
+ integration : RpcIntegration | None = None ,
30
+ organization : Organization | None = None ,
31
+ sentry_app_installation : RpcSentryAppInstallation | None = None ,
32
+ ) -> Mapping [str , Any ]:
26
33
"""
27
34
Build the "available action" objects for the API. Each one can have different fields.
28
35
@@ -45,28 +52,32 @@ def build_action_response(
45
52
action_response ["integrationId" ] = integration .id
46
53
47
54
if registered_type .type == AlertRuleTriggerAction .Type .PAGERDUTY :
55
+ if organization is None :
56
+ raise Exception ("Organization is required for PAGERDUTY actions" )
48
57
action_response ["options" ] = [
49
58
{"value" : id , "label" : service_name }
50
59
for id , service_name in get_pagerduty_services (organization .id , integration .id )
51
60
]
52
61
elif registered_type .type == AlertRuleTriggerAction .Type .OPSGENIE :
62
+ if organization is None :
63
+ raise Exception ("Organization is required for OPSGENIE actions" )
53
64
action_response ["options" ] = [
54
65
{"value" : id , "label" : team }
55
66
for id , team in get_opsgenie_teams (organization .id , integration .id )
56
67
]
57
68
58
69
elif sentry_app_installation :
59
70
action_response ["sentryAppName" ] = sentry_app_installation .sentry_app .name
60
- action_response ["sentryAppId" ] = sentry_app_installation .sentry_app_id
71
+ action_response ["sentryAppId" ] = sentry_app_installation .sentry_app . id
61
72
action_response ["sentryAppInstallationUuid" ] = sentry_app_installation .uuid
62
- action_response ["status" ] = SentryAppStatus .as_str (
63
- sentry_app_installation .sentry_app .status
64
- )
73
+ action_response ["status" ] = sentry_app_installation .sentry_app .status
65
74
66
75
# Sentry Apps can be alertable but not have an Alert Rule UI Component
67
- component = sentry_app_installation .prepare_sentry_app_components ("alert-rule-action" )
76
+ component = app_service .prepare_sentry_app_components (
77
+ installation_id = sentry_app_installation .id , component_type = "alert-rule-action"
78
+ )
68
79
if component :
69
- action_response ["settings" ] = component .schema .get ("settings" , {})
80
+ action_response ["settings" ] = component .app_schema .get ("settings" , {})
70
81
71
82
return action_response
72
83
@@ -87,7 +98,7 @@ def get(self, request: Request, organization) -> Response:
87
98
actions = []
88
99
89
100
# Cache Integration objects in this data structure to save DB calls.
90
- provider_integrations = defaultdict (list )
101
+ provider_integrations : DefaultDict [ str , List [ RpcIntegration ]] = defaultdict (list )
91
102
for integration in get_available_action_integrations_for_org (organization ):
92
103
provider_integrations [integration .provider ].append (integration )
93
104
@@ -103,13 +114,13 @@ def get(self, request: Request, organization) -> Response:
103
114
104
115
# Add all alertable SentryApps to the list.
105
116
elif registered_type .type == AlertRuleTriggerAction .Type .SENTRY_APP :
117
+ installs = app_service .get_installed_for_organization (
118
+ organization_id = organization .id
119
+ )
106
120
actions += [
107
121
build_action_response (registered_type , sentry_app_installation = install )
108
- for install in SentryAppInstallation .objects .get_installed_for_organization (
109
- organization .id
110
- ).filter (
111
- sentry_app__is_alertable = True ,
112
- )
122
+ for install in installs
123
+ if install .sentry_app .is_alertable
113
124
]
114
125
115
126
else :
0 commit comments