/
core.py
157 lines (122 loc) · 3.99 KB
/
core.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
from __future__ import absolute_import
import logging
from click import echo
from django.conf import settings
from django.db import connections, transaction
from django.db.utils import OperationalError, ProgrammingError
from django.db.models.signals import post_syncdb, post_save
from functools import wraps
from pkg_resources import parse_version as Version
from sentry import options
from sentry.models import (
Organization, OrganizationMember, Project, User, Team, ProjectKey
)
from sentry.utils import db
PROJECT_SEQUENCE_FIX = """
SELECT setval('sentry_project_id_seq', (
SELECT GREATEST(MAX(id) + 1, nextval('sentry_project_id_seq')) - 1
FROM sentry_project))
"""
def handle_db_failure(func):
@wraps(func)
def wrapped(*args, **kwargs):
try:
with transaction.atomic():
return func(*args, **kwargs)
except (ProgrammingError, OperationalError):
logging.exception('Failed processing signal %s', func.__name__)
return
return wrapped
def create_default_projects(created_models, app=None, verbosity=2, **kwargs):
if app and app.__name__ != 'sentry.models':
return
if Project not in created_models:
return
create_default_project(
id=settings.SENTRY_PROJECT,
name='Internal',
slug='internal',
verbosity=verbosity,
)
if settings.SENTRY_FRONTEND_PROJECT:
create_default_project(
id=settings.SENTRY_FRONTEND_PROJECT,
name='Frontend',
slug='frontend',
verbosity=verbosity,
)
def create_default_project(id, name, slug, verbosity=2, **kwargs):
if Project.objects.filter(id=id).exists():
return
try:
user = User.objects.filter(is_superuser=True)[0]
except IndexError:
user = None
org, _ = Organization.objects.get_or_create(
slug='sentry', defaults={
'name': 'Sentry',
}
)
if user:
OrganizationMember.objects.get_or_create(
user=user,
organization=org,
role='owner',
)
team, _ = Team.objects.get_or_create(
organization=org, slug='sentry', defaults={
'name': 'Sentry',
}
)
project = Project.objects.create(
id=id,
public=False,
name=name,
slug=slug,
organization=team.organization,
**kwargs
)
project.add_team(team)
# HACK: manually update the ID after insert due to Postgres
# sequence issues. Seriously, fuck everything about this.
if db.is_postgres(project._state.db):
connection = connections[project._state.db]
cursor = connection.cursor()
cursor.execute(PROJECT_SEQUENCE_FIX)
project.update_option('sentry:origins', ['*'])
if verbosity > 0:
echo('Created internal Sentry project (slug=%s, id=%s)' % (project.slug, project.id))
return project
def set_sentry_version(latest=None, **kwargs):
import sentry
current = sentry.VERSION
version = options.get('sentry:latest_version')
for ver in (current, version):
if Version(ver) >= Version(latest):
latest = ver
if latest == version:
return
options.set('sentry:latest_version', (latest or current))
def create_keys_for_project(instance, created, app=None, **kwargs):
if app and app.__name__ != 'sentry.models':
return
if not created or kwargs.get('raw'):
return
if not ProjectKey.objects.filter(project=instance).exists():
ProjectKey.objects.create(
project=instance,
label='Default',
)
# Anything that relies on default objects that may not exist with default
# fields should be wrapped in handle_db_failure
post_syncdb.connect(
handle_db_failure(create_default_projects),
dispatch_uid="create_default_project",
weak=False,
)
post_save.connect(
handle_db_failure(create_keys_for_project),
sender=Project,
dispatch_uid="create_keys_for_project",
weak=False,
)