Skip to content

Commit c7c742d

Browse files
committedDec 7, 2015
Move system.url-prefix to option
This was a bit of a yak shave since it introduced a nice circular dependency. This also required an addition of a override_options helper
1 parent d31f146 commit c7c742d

File tree

21 files changed

+71
-52
lines changed

21 files changed

+71
-52
lines changed
 

‎api-docs/generator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929

3030
OUTPUT_PATH = os.path.join(HERE, 'cache')
31-
HOST = urlparse.urlparse(settings.SENTRY_URL_PREFIX).netloc
31+
HOST = urlparse.urlparse(settings.SENTRY_OPTIONS['system.url-prefix']).netloc
3232

3333

3434
# We don't care about you, go away

‎api-docs/sentry.conf.py

+1
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,4 @@
8181
SECRET_KEY = 'super secret secret key'
8282

8383
SENTRY_OPTIONS['system.admin-email'] = 'admin@getsentry.com'
84+
SENTRY_OPTIONS['system.url-prefix'] = SENTRY_URL_PREFIX

‎src/sentry/conf/server.py

-3
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,6 @@ def create_partitioned_queues(name):
614614
'OperationalError',
615615
)
616616

617-
# Absolute URL to the sentry root directory. Should not include a trailing slash.
618-
SENTRY_URL_PREFIX = ''
619-
620617
# Should we send the beacon to the upstream server?
621618
SENTRY_BEACON = True
622619

‎src/sentry/http.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import requests
1414
import warnings
1515

16+
from sentry import options
1617
from django.conf import settings
1718
from django.core.exceptions import SuspiciousOperation
1819
from ipaddr import IPNetwork
@@ -36,9 +37,7 @@ class ZeroReturnError(Exception):
3637

3738

3839
def get_server_hostname():
39-
# TODO(dcramer): Ideally this would parse at runtime, but we currently
40-
# change the URL prefix when runner initializes which may be post-import
41-
return urlparse(settings.SENTRY_URL_PREFIX).hostname
40+
return urlparse(options.get('system.url-prefix')).hostname
4241

4342

4443
def is_valid_url(url):

‎src/sentry/middleware/env.py

-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
from __future__ import absolute_import
22

3-
from django.conf import settings
4-
from django.core.urlresolvers import reverse
5-
63
from sentry.app import env
74

85

96
class SentryEnvMiddleware(object):
107
def process_request(self, request):
11-
# HACK: bootstrap some env crud if we haven't yet
12-
if not settings.SENTRY_URL_PREFIX:
13-
settings.SENTRY_URL_PREFIX = request.build_absolute_uri(reverse('sentry')).strip('/')
14-
158
# bind request to env
169
env.request = request

‎src/sentry/models/lostpasswordhash.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ def is_valid(self):
4646
return self.date_added > timezone.now() - timedelta(hours=48)
4747

4848
def send_recover_mail(self):
49+
from sentry import options
4950
from sentry.utils.email import MessageBuilder
5051

5152
context = {
5253
'user': self.user,
53-
'domain': urlparse(settings.SENTRY_URL_PREFIX).hostname,
54+
'domain': urlparse(options.get('system.url-prefix')).hostname,
5455
'url': absolute_uri(reverse(
5556
'sentry-account-recover-confirm',
5657
args=[self.user.id, self.hash]

‎src/sentry/models/projectkey.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from django.utils import timezone
2020
from django.utils.translation import ugettext_lazy as _
2121

22+
from sentry import options
2223
from sentry.db.models import (
2324
Model, BaseManager, BoundedPositiveIntegerField, FlexibleForeignKey,
2425
sane_repr
@@ -121,7 +122,11 @@ def get_dsn(self, domain=None, secure=True, public=False):
121122
key = self.public_key
122123
url = settings.SENTRY_PUBLIC_ENDPOINT or settings.SENTRY_ENDPOINT
123124

124-
urlparts = urlparse(url or settings.SENTRY_URL_PREFIX)
125+
if url:
126+
urlparts = urlparse(url)
127+
else:
128+
urlparts = urlparse(options.get('system.url-prefix'))
129+
125130
return '%s://%s@%s/%s' % (
126131
urlparts.scheme,
127132
key,

‎src/sentry/options/defaults.py

+3
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@
1818
register('system.debug', default=False, flags=FLAG_NOSTORE)
1919
register('system.secret-key', flags=FLAG_NOSTORE)
2020
register('redis.options', default={}, flags=FLAG_NOSTORE)
21+
22+
# Absolute URL to the sentry root directory. Should not include a trailing slash.
23+
register('system.url-prefix', ttl=60, grace=3600)

‎src/sentry/options/store.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from random import random
1414

1515
from django.utils import timezone
16+
from django.utils.functional import cached_property
1617
from sentry.db.models.query import create_or_update
17-
from sentry.models import Option
1818
from sentry.utils.hashlib import md5
1919

2020

@@ -59,6 +59,11 @@ def __init__(self, cache=None, ttl=None):
5959
self.ttl = ttl
6060
self.flush_local_cache()
6161

62+
@cached_property
63+
def model(self):
64+
from sentry.models.option import Option
65+
return Option
66+
6267
def make_key(self, name, default, type, flags, ttl, grace):
6368
return Key(name, default, type, flags, int(ttl), int(grace), _make_cache_key(name))
6469

@@ -156,8 +161,8 @@ def get_store(self, key):
156161
is limited at the moment.
157162
"""
158163
try:
159-
value = Option.objects.get(key=key.name).value
160-
except Option.DoesNotExist:
164+
value = self.model.objects.get(key=key.name).value
165+
except self.model.DoesNotExist:
161166
value = None
162167
except Exception as e:
163168
logger.exception(unicode(e))
@@ -185,7 +190,7 @@ def set(self, key, value):
185190

186191
def set_store(self, key, value):
187192
create_or_update(
188-
model=Option,
193+
model=self.model,
189194
key=key.name,
190195
values={
191196
'value': value,
@@ -215,7 +220,7 @@ def delete(self, key):
215220
return self.delete_cache(key)
216221

217222
def delete_store(self, key):
218-
Option.objects.filter(key=key.name).delete()
223+
self.model.objects.filter(key=key.name).delete()
219224

220225
def delete_cache(self, key):
221226
cache_key = key.cache_key

‎src/sentry/runner/initializer.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def bootstrap_options(settings, config):
7777
and convert options into Django settings that are
7878
required to even initialize the rest of the app.
7979
"""
80+
from sentry import options as _ # NOQA
8081
if config is None:
8182
return
8283
from sentry.utils.yaml import safe_load
@@ -201,13 +202,11 @@ def apply_legacy_settings(settings):
201202
"Use SENTRY_OPTIONS instead, key 'system.admin-email'", DeprecationWarning)
202203
settings.SENTRY_OPTIONS['system.admin-email'] = settings.SENTRY_ADMIN_EMAIL
203204

204-
if settings.SENTRY_URL_PREFIX in ('', 'http://sentry.example.com') and not settings.DEBUG:
205-
# Maybe also point to a piece of documentation for more information?
206-
# This directly coincides with users getting the awkward
207-
# `ALLOWED_HOSTS` exception.
208-
show_big_error('SENTRY_URL_PREFIX is not configured')
209-
# Set `ALLOWED_HOSTS` to the catch-all so it works
210-
settings.ALLOWED_HOSTS = ['*']
205+
if not settings.SENTRY_OPTIONS.get('system.url-prefix') and hasattr(settings, 'SENTRY_URL_PREFIX'):
206+
import warnings
207+
warnings.warn('SENTRY_URL_PREFIX is deprecated.'
208+
"Use SENTRY_OPTIONS instead, key 'system.url-prefix'", DeprecationWarning)
209+
settings.SENTRY_OPTIONS['system.url-prefix'] = settings.SENTRY_URL_PREFIX
211210

212211
if settings.TIME_ZONE != 'UTC':
213212
# non-UTC timezones are not supported

‎src/sentry/runner/settings.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,6 @@
160160
# Web Server #
161161
##############
162162
163-
# You MUST configure the absolute URI root for Sentry:
164-
SENTRY_URL_PREFIX = 'http://sentry.example.com' # No trailing slash!
165-
166163
# If you're using a reverse SSL proxy, you should enable the X-Forwarded-Proto
167164
# header and uncomment the following settings
168165
# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
@@ -214,6 +211,15 @@
214211
# system.admin-email: 'your.name@example.com'
215212
system.admin-email: ''
216213
214+
215+
##############
216+
# Web Server #
217+
##############
218+
219+
# You MUST configure the absolute URI root for Sentry:
220+
system.url-prefix: 'http://sentry.example.com' # No trailing slash!
221+
222+
217223
########
218224
# etc. #
219225
########

‎src/sentry/templatetags/sentry_react.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def get_react_config(context):
5959

6060
context = {
6161
'singleOrganization': settings.SENTRY_SINGLE_ORGANIZATION,
62-
'urlPrefix': settings.SENTRY_URL_PREFIX,
62+
'urlPrefix': options.get('system.url-prefix'),
6363
'version': version_info,
6464
'features': enabled_features,
6565
'mediaUrl': get_asset_url('sentry', ''),

‎src/sentry/testutils/cases.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from sentry.utils import json
3838

3939
from .fixtures import Fixtures
40-
from .helpers import AuthProvider, Feature, get_auth_header, TaskRunner
40+
from .helpers import AuthProvider, Feature, get_auth_header, TaskRunner, override_options
4141

4242

4343
class BaseTestCase(Fixtures, Exam):
@@ -206,6 +206,13 @@ def _postWithReferer(self, data, key=None, referer='getsentry.com', protocol='4'
206206
)
207207
return resp
208208

209+
def options(self, options):
210+
"""
211+
A context manager that temporarily sets a global option and reverts
212+
back to the original value when exiting the context.
213+
"""
214+
return override_options(options)
215+
209216
_postWithSignature = _postWithHeader
210217
_postWithNewSignature = _postWithHeader
211218

‎src/sentry/testutils/helpers/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
from .features import * # NOQA
1313
from .link_header import * # NOQA
1414
from .task_runner import * # NOQA
15+
from .options import * # NOQA

‎src/sentry/utils/http.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@
1515
from ipaddr import IPNetwork
1616

1717
from django.conf import settings
18+
from sentry import options
1819

1920

2021
ParsedUriMatch = namedtuple('ParsedUriMatch', ['scheme', 'domain', 'path'])
2122

2223

2324
def absolute_uri(url=None):
2425
if not url:
25-
return settings.SENTRY_URL_PREFIX
26-
return urljoin(settings.SENTRY_URL_PREFIX.rstrip('/') + '/', url.lstrip('/'))
26+
return options.get('system.url-prefix')
27+
return urljoin(options.get('system.url-prefix').rstrip('/') + '/', url.lstrip('/'))
2728

2829

2930
def safe_urlencode(params, doseq=0):

‎src/sentry/utils/pytest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def pytest_configure(config):
6363
middleware[sudo] = 'sentry.testutils.middleware.SudoMiddleware'
6464
settings.MIDDLEWARE_CLASSES = tuple(middleware)
6565

66-
settings.SENTRY_URL_PREFIX = 'http://testserver'
66+
settings.SENTRY_OPTIONS['system.url-prefix'] = 'http://testserver'
6767

6868
# enable draft features
6969
settings.SENTRY_ENABLE_EMAIL_REPLIES = True

‎src/sentry/web/helpers.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ def get_login_url(reset=False):
4545

4646

4747
def get_default_context(request, existing_context=None, team=None):
48+
from sentry import options
4849
from sentry.plugins import plugins
4950

5051
context = {
5152
'EVENTS_PER_PAGE': EVENTS_PER_PAGE,
52-
'URL_PREFIX': settings.SENTRY_URL_PREFIX,
53+
'URL_PREFIX': options.get('system.url-prefix'),
5354
'SINGLE_ORGANIZATION': settings.SENTRY_SINGLE_ORGANIZATION,
5455
'PLUGINS': plugins,
5556
'ALLOWED_HOSTS': settings.ALLOWED_HOSTS,

‎tests/sentry/models/test_organizationmember.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def test_token_generation_unicode_key(self):
4545
def test_send_invite_email(self):
4646
organization = self.create_organization()
4747
member = OrganizationMember(id=1, organization=organization, email='foo@example.com')
48-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
48+
with self.options({'system.url-prefix': 'http://example.com'}):
4949
member.send_invite_email()
5050

5151
assert len(mail.outbox) == 1
@@ -57,7 +57,7 @@ def test_send_invite_email(self):
5757
def test_send_sso_link_email(self):
5858
organization = self.create_organization()
5959
member = OrganizationMember(id=1, organization=organization, email='foo@example.com')
60-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
60+
with self.options({'system.url-prefix': 'http://example.com'}):
6161
member.send_invite_email()
6262

6363
assert len(mail.outbox) == 1

‎tests/sentry/models/tests.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@
2121
class ProjectKeyTest(TestCase):
2222
def test_get_dsn(self):
2323
key = ProjectKey(project_id=1, public_key='public', secret_key='secret')
24-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
24+
with self.options({'system.url-prefix': 'http://example.com'}):
2525
self.assertEquals(key.get_dsn(), 'http://public:secret@example.com/1')
2626

2727
def test_get_dsn_with_ssl(self):
2828
key = ProjectKey(project_id=1, public_key='public', secret_key='secret')
29-
with self.settings(SENTRY_URL_PREFIX='https://example.com'):
29+
with self.options({'system.url-prefix': 'https://example.com'}):
3030
self.assertEquals(key.get_dsn(), 'https://public:secret@example.com/1')
3131

3232
def test_get_dsn_with_port(self):
3333
key = ProjectKey(project_id=1, public_key='public', secret_key='secret')
34-
with self.settings(SENTRY_URL_PREFIX='http://example.com:81'):
34+
with self.options({'system.url-prefix': 'http://example.com:81'}):
3535
self.assertEquals(key.get_dsn(), 'http://public:secret@example.com:81/1')
3636

3737
def test_get_dsn_with_public_endpoint_setting(self):
@@ -59,7 +59,7 @@ def password_hash(self):
5959
)
6060

6161
def test_send_recover_mail(self):
62-
with self.settings(SENTRY_URL_PREFIX='http://testserver'), self.tasks():
62+
with self.options({'system.url-prefix': 'http://testserver'}), self.tasks():
6363
self.password_hash.send_recover_mail()
6464

6565
assert len(mail.outbox) == 1

‎tests/sentry/plugins/mail/tests.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_simple_notification(self):
4747

4848
notification = Notification(event=event, rule=rule)
4949

50-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
50+
with self.options({'system.url-prefix': 'http://example.com'}):
5151
self.plugin.notify(notification)
5252

5353
msg = mail.outbox[0]
@@ -76,7 +76,7 @@ def test_notify_users_renders_interfaces_with_utf8(self, _send_mail):
7676

7777
notification = Notification(event=event)
7878

79-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
79+
with self.options({'system.url-prefix': 'http://example.com'}):
8080
self.plugin.notify(notification)
8181

8282
stacktrace.get_title.assert_called_once_with()
@@ -103,7 +103,7 @@ def test_notify_users_renders_interfaces_with_utf8_fix_issue_422(self, _send_mai
103103

104104
notification = Notification(event=event)
105105

106-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
106+
with self.options({'system.url-prefix': 'http://example.com'}):
107107
self.plugin.notify(notification)
108108

109109
stacktrace.get_title.assert_called_once_with()
@@ -129,7 +129,7 @@ def test_notify_users_does_email(self, _send_mail):
129129

130130
notification = Notification(event=event)
131131

132-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
132+
with self.options({'system.url-prefix': 'http://example.com'}):
133133
self.plugin.notify(notification)
134134

135135
assert _send_mail.call_count is 1
@@ -159,7 +159,7 @@ def test_multiline_error(self, _send_mail):
159159

160160
notification = Notification(event=event)
161161

162-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
162+
with self.options({'system.url-prefix': 'http://example.com'}):
163163
self.plugin.notify(notification)
164164

165165
assert _send_mail.call_count is 1
@@ -226,7 +226,7 @@ def test_notify_users_with_utf8_subject(self):
226226

227227
notification = Notification(event=event)
228228

229-
with self.settings(SENTRY_URL_PREFIX='http://example.com'):
229+
with self.options({'system.url-prefix': 'http://example.com'}):
230230
self.plugin.notify(notification)
231231

232232
msg = mail.outbox[0]

‎tests/sentry/utils/http/tests.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
import mock
66

7-
from django.conf import settings
87
from exam import fixture
98

9+
from sentry import options
1010
from sentry.models import Project
1111
from sentry.testutils import TestCase
1212
from sentry.utils.http import (
@@ -16,10 +16,10 @@
1616

1717
class AbsoluteUriTest(TestCase):
1818
def test_without_path(self):
19-
assert absolute_uri() == settings.SENTRY_URL_PREFIX
19+
assert absolute_uri() == options.get('system.url-prefix')
2020

2121
def test_with_path(self):
22-
assert absolute_uri('/foo/bar') == '%s/foo/bar' % (settings.SENTRY_URL_PREFIX,)
22+
assert absolute_uri('/foo/bar') == '%s/foo/bar' % (options.get('system.url-prefix'),)
2323

2424

2525
class SameDomainTestCase(TestCase):

0 commit comments

Comments
 (0)
Please sign in to comment.