示例#1
0
文件: redis.py 项目: huyujiang/sentry
def get_cluster_from_options(backend, options, cluster_manager=clusters):
    cluster_option_name = 'cluster'
    default_cluster_name = 'default'
    cluster_constructor_option_names = frozenset(('hosts',))

    options = options.copy()
    cluster_options = {key: options.pop(key) for key in set(options.keys()).intersection(cluster_constructor_option_names)}
    if cluster_options:
        if cluster_option_name in options:
            raise InvalidConfiguration(
                'Cannot provide both named cluster ({!r}) and cluster configuration ({}) options.'.format(
                    cluster_option_name,
                    ', '.join(map(repr, cluster_constructor_option_names)),
                )
            )
        else:
            warnings.warn(
                'Providing Redis cluster configuration options ({}) to {!r} is '
                'deprecated, please update your configuration to use named Redis '
                'clusters ({!r}).'.format(
                    ', '.join(map(repr, cluster_constructor_option_names)),
                    backend,
                    cluster_option_name,
                ),
                DeprecationWarning,
                stacklevel=2
            )
        cluster = rb.Cluster(pool_cls=_shared_pool, **cluster_options)
    else:
        cluster = cluster_manager.get(options.pop(cluster_option_name, default_cluster_name))

    return cluster, options
示例#2
0
def check_versions(service, versions, required, recommended=None):
    """
    Check that hosts fulfill version requirements.

    :param service: service label, such as ``Redis``
    :param versions: mapping of host to ``Version``
    :param required: lowest supported ``Version``. If any host does not fulfill
        this requirement, an ``InvalidConfiguration`` exception is raised.
    :param recommended: recommended version. If any host does not fulfill this
        requirement, a ``PendingDeprecationWarning`` is raised.
    """
    # x = (host, version)
    must_upgrade = dict([x for x in versions.items() if required > x[1]])
    if must_upgrade:
        raise InvalidConfiguration(
            make_upgrade_message(service, "must", required, must_upgrade))

    if recommended:
        # x = (host, version)
        should_upgrade = dict(
            [x for x in versions.items() if recommended > x[1]])
        if should_upgrade:
            warnings.warn(
                make_upgrade_message(service, "should", recommended,
                                     should_upgrade),
                PendingDeprecationWarning,
            )
示例#3
0
def get_cluster_from_options(setting, options, cluster_manager=clusters):
    cluster_option_name = 'cluster'
    default_cluster_name = 'default'
    cluster_constructor_option_names = frozenset(('hosts',))

    options = options.copy()
    cluster_options = {key: options.pop(key) for key in set(options.keys()).intersection(cluster_constructor_option_names)}
    if cluster_options:
        if cluster_option_name in options:
            raise InvalidConfiguration(
                'Cannot provide both named cluster ({!r}) and cluster configuration ({}) options.'.format(
                    cluster_option_name,
                    ', '.join(map(repr, cluster_constructor_option_names)),
                )
            )
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    '{} parameter of {}'.format(
                        ', '.join(map(repr, cluster_constructor_option_names)),
                        setting,
                    ),
                    '{}["{}"]'.format(
                        setting,
                        cluster_option_name,
                    ),
                    removed_in_version='8.5',
                ),
                stacklevel=2
            )
        cluster = rb.Cluster(pool_cls=_shared_pool, **cluster_options)
    else:
        cluster = cluster_manager.get(options.pop(cluster_option_name, default_cluster_name))

    return cluster, options
示例#4
0
文件: redis.py 项目: ForkRepo/sentry
def get_cluster_from_options(setting, options, cluster_manager=clusters):
    cluster_option_name = 'cluster'
    default_cluster_name = 'default'
    cluster_constructor_option_names = frozenset(('hosts',))

    options = options.copy()
    cluster_options = {key: options.pop(key) for key in set(options.keys()).intersection(cluster_constructor_option_names)}
    if cluster_options:
        if cluster_option_name in options:
            raise InvalidConfiguration(
                'Cannot provide both named cluster ({!r}) and cluster configuration ({}) options.'.format(
                    cluster_option_name,
                    ', '.join(map(repr, cluster_constructor_option_names)),
                )
            )
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    '{} parameter of {}'.format(
                        ', '.join(map(repr, cluster_constructor_option_names)),
                        setting,
                    ),
                    '{}["{}"]'.format(
                        setting,
                        cluster_option_name,
                    ),
                    removed_in_version='8.5',
                ),
                stacklevel=2
            )
        cluster = rb.Cluster(pool_cls=_shared_pool, **cluster_options)
    else:
        cluster = cluster_manager.get(options.pop(cluster_option_name, default_cluster_name))

    return cluster, options
示例#5
0
def initialize_app(config, skip_service_validation=False):
    settings = config['settings']

    bootstrap_options(settings, config['options'])

    configure_structlog()

    if 'south' in settings.INSTALLED_APPS:
        fix_south(settings)

    apply_legacy_settings(settings)

    bind_cache_to_option_store()

    # Commonly setups don't correctly configure themselves for production envs
    # so lets try to provide a bit more guidance
    if settings.CELERY_ALWAYS_EAGER and not settings.DEBUG:
        warnings.warn(
            'Sentry is configured to run asynchronous tasks in-process. '
            'This is not recommended within production environments. '
            'See https://docs.sentry.io/on-premise/server/queue/ for more information.'
        )

    if settings.SENTRY_SINGLE_ORGANIZATION:
        settings.SENTRY_FEATURES['organizations:create'] = False

    if not hasattr(settings, 'SUDO_COOKIE_SECURE'):
        settings.SUDO_COOKIE_SECURE = getattr(settings, 'SESSION_COOKIE_SECURE', False)
    if not hasattr(settings, 'SUDO_COOKIE_DOMAIN'):
        settings.SUDO_COOKIE_DOMAIN = getattr(settings, 'SESSION_COOKIE_DOMAIN', None)
    if not hasattr(settings, 'SUDO_COOKIE_PATH'):
        settings.SUDO_COOKIE_PATH = getattr(settings, 'SESSION_COOKIE_PATH', '/')

    if not hasattr(settings, 'CSRF_COOKIE_SECURE'):
        settings.CSRF_COOKIE_SECURE = getattr(settings, 'SESSION_COOKIE_SECURE', False)
    if not hasattr(settings, 'CSRF_COOKIE_DOMAIN'):
        settings.CSRF_COOKIE_DOMAIN = getattr(settings, 'SESSION_COOKIE_DOMAIN', None)
    if not hasattr(settings, 'CSRF_COOKIE_PATH'):
        settings.CSRF_COOKIE_PATH = getattr(settings, 'SESSION_COOKIE_PATH', '/')

    settings.CACHES['default']['VERSION'] = settings.CACHE_VERSION

    settings.ASSET_VERSION = get_asset_version(settings)
    settings.STATIC_URL = settings.STATIC_URL.format(
        version=settings.ASSET_VERSION,
    )

    register_plugins(settings)

    initialize_receivers()

    validate_options(settings)

    setup_services(validate=not skip_service_validation)

    from django.utils import timezone
    from sentry.app import env
    from sentry.runner.settings import get_sentry_conf
    env.data['config'] = get_sentry_conf()
    env.data['start_date'] = timezone.now()
示例#6
0
def bootstrap_options(settings, config=None):
    """
    Quickly bootstrap options that come in from a config file
    and convert options into Django settings that are
    required to even initialize the rest of the app.
    """
    # Make sure our options have gotten registered
    from sentry.options import load_defaults
    load_defaults()

    options = {}
    if config is not None:
        # Attempt to load our config yaml file
        from sentry.utils.yaml import safe_load
        from yaml.parser import ParserError
        from yaml.scanner import ScannerError
        try:
            with open(config, 'rb') as fp:
                options = safe_load(fp)
        except IOError:
            # Gracefully fail if yaml file doesn't exist
            pass
        except (AttributeError, ParserError, ScannerError) as e:
            from .importer import ConfigurationError
            raise ConfigurationError('Malformed config.yml file: %s' % unicode(e))

        # Empty options file, so fail gracefully
        if options is None:
            options = {}
        # Options needs to be a dict
        elif not isinstance(options, dict):
            from .importer import ConfigurationError
            raise ConfigurationError('Malformed config.yml file')

    from sentry.conf.server import DEAD

    # First move options from settings into options
    for k, v in options_mapper.iteritems():
        if getattr(settings, v, DEAD) is not DEAD and k not in options:
            warnings.warn(
                DeprecatedSettingWarning(
                    options_mapper[k],
                    "SENTRY_OPTIONS['%s']" % k,
                )
            )
            options[k] = getattr(settings, v)

    # Stuff everything else into SENTRY_OPTIONS
    # these will be validated later after bootstrapping
    for k, v in options.iteritems():
        settings.SENTRY_OPTIONS[k] = v

    # Now go back through all of SENTRY_OPTIONS and promote
    # back into settings. This catches the case when values are defined
    # only in SENTRY_OPTIONS and no config.yml file
    for o in (settings.SENTRY_DEFAULT_OPTIONS, settings.SENTRY_OPTIONS):
        for k, v in o.iteritems():
            if k in options_mapper:
                # Escalate the few needed to actually get the app bootstrapped into settings
                setattr(settings, options_mapper[k], v)
示例#7
0
def get_cluster_from_options(setting, options, cluster_manager=clusters):
    cluster_option_name = "cluster"
    default_cluster_name = "default"
    cluster_constructor_option_names = frozenset(("hosts",))

    options = options.copy()
    cluster_options = {
        key: options.pop(key)
        for key in set(options.keys()).intersection(cluster_constructor_option_names)
    }
    if cluster_options:
        if cluster_option_name in options:
            raise InvalidConfiguration(
                "Cannot provide both named cluster ({!r}) and cluster configuration ({}) options.".format(
                    cluster_option_name, ", ".join(map(repr, cluster_constructor_option_names))
                )
            )
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    "{} parameter of {}".format(
                        ", ".join(map(repr, cluster_constructor_option_names)), setting
                    ),
                    f'{setting}["{cluster_option_name}"]',
                    removed_in_version="8.5",
                ),
                stacklevel=2,
            )
        cluster = rb.Cluster(pool_cls=_shared_pool, **cluster_options)
    else:
        cluster = cluster_manager.get(options.pop(cluster_option_name, default_cluster_name))

    return cluster, options
示例#8
0
def initialize_app(config, skip_backend_validation=False):
    settings = config['settings']

    bootstrap_options(settings, config['options'])

    configure_structlog()

    fix_south(settings)

    apply_legacy_settings(settings)

    bind_cache_to_option_store()

    install_plugin_apps(settings)

    # Commonly setups don't correctly configure themselves for production envs
    # so lets try to provide a bit more guidance
    if settings.CELERY_ALWAYS_EAGER and not settings.DEBUG:
        warnings.warn(
            'Sentry is configured to run asynchronous tasks in-process. '
            'This is not recommended within production environments. '
            'See https://docs.getsentry.com/on-premise/server/queue/ for more information.'
        )

    if settings.SENTRY_SINGLE_ORGANIZATION:
        settings.SENTRY_FEATURES['organizations:create'] = False

    settings.SUDO_COOKIE_SECURE = getattr(settings, 'SESSION_COOKIE_SECURE',
                                          False)
    settings.SUDO_COOKIE_DOMAIN = getattr(settings, 'SESSION_COOKIE_DOMAIN',
                                          None)
    settings.SUDO_COOKIE_PATH = getattr(settings, 'SESSION_COOKIE_PATH', '/')

    settings.CSRF_COOKIE_SECURE = getattr(settings, 'SESSION_COOKIE_SECURE',
                                          False)
    settings.CSRF_COOKIE_DOMAIN = getattr(settings, 'SESSION_COOKIE_DOMAIN',
                                          None)
    settings.CSRF_COOKIE_PATH = getattr(settings, 'SESSION_COOKIE_PATH', '/')

    settings.CACHES['default']['VERSION'] = settings.CACHE_VERSION

    settings.ASSET_VERSION = get_asset_version(settings)
    settings.STATIC_URL = settings.STATIC_URL.format(
        version=settings.ASSET_VERSION, )

    register_plugins(settings)

    initialize_receivers()

    validate_options(settings)

    if not skip_backend_validation:
        validate_backends()

    from django.utils import timezone
    from sentry.app import env
    from sentry.runner.settings import get_sentry_conf
    env.data['config'] = get_sentry_conf()
    env.data['start_date'] = timezone.now()
示例#9
0
 def _setup(self):
     backend = import_string(self._backend)
     if backend in self._dangerous:
         warnings.warn(
             warnings.UnsupportedBackend(
                 u'The {!r} backend for {} is not recommended '
                 'for production use.'.format(self._backend, self._base)))
     instance = backend(**self._options)
     self._wrapped = instance
示例#10
0
文件: redis.py 项目: huyujiang/sentry
def make_rb_cluster(*args, **kwargs):
    # This uses the standard library `warnings`, since this is provided for
    # plugin compatibility but isn't actionable by the system administrator.
    import warnings
    warnings.warn(
        'Direct Redis cluster construction is deprecated, please use named clusters.',
        DeprecationWarning,
    )
    return _make_rb_cluster(*args, **kwargs)
示例#11
0
 def _setup(self):
     backend = import_string(self._backend)
     assert issubclass(backend, Service)
     if backend in self._dangerous:
         warnings.warn(
             warnings.UnsupportedBackend(
                 u"The {!r} backend for {} is not recommended "
                 "for production use.".format(self._backend, self._base)))
     instance = backend(**self._options)
     self._wrapped = instance
示例#12
0
def make_rb_cluster(*args, **kwargs):
    # This uses the standard library `warnings`, since this is provided for
    # plugin compatibility but isn't actionable by the system administrator.
    import warnings
    warnings.warn(
        'Direct Redis cluster construction is deprecated, please use named clusters. '
        'Direct cluster construction will be removed in Sentry 8.5.',
        DeprecationWarning,
    )
    return _make_rb_cluster(*args, **kwargs)
示例#13
0
def get_instance(attribute, options, dangerous=()):
    value = getattr(settings, attribute)

    cls = import_string(value)
    if cls in dangerous:
        warnings.warn(
            warnings.UnsupportedBackend(
                u'The {!r} backend for {} is not recommended '
                'for production use.'.format(value, attribute)))

    return cls(**options)
示例#14
0
 def _setup(self):
     backend = import_string(self._backend)
     if backend in self._dangerous:
         warnings.warn(
             warnings.UnsupportedBackend(
                 u'The {!r} backend for {} is not recommended '
                 'for production use.'.format(self._backend, self._base)
             )
         )
     instance = backend(**self._options)
     self._wrapped = instance
示例#15
0
def initialize_app(config, skip_backend_validation=False):
    settings = config["settings"]

    bootstrap_options(settings, config["options"])

    fix_south(settings)

    apply_legacy_settings(settings)

    bind_cache_to_option_store()

    install_plugin_apps(settings)

    # Commonly setups don't correctly configure themselves for production envs
    # so lets try to provide a bit more guidance
    if settings.CELERY_ALWAYS_EAGER and not settings.DEBUG:
        warnings.warn(
            "Sentry is configured to run asynchronous tasks in-process. "
            "This is not recommended within production environments. "
            "See https://docs.getsentry.com/on-premise/server/queue/ for more information."
        )

    if settings.SENTRY_SINGLE_ORGANIZATION:
        settings.SENTRY_FEATURES["organizations:create"] = False

    settings.SUDO_COOKIE_SECURE = getattr(settings, "SESSION_COOKIE_SECURE", False)
    settings.SUDO_COOKIE_DOMAIN = getattr(settings, "SESSION_COOKIE_DOMAIN", None)
    settings.SUDO_COOKIE_PATH = getattr(settings, "SESSION_COOKIE_PATH", "/")

    settings.CSRF_COOKIE_SECURE = getattr(settings, "SESSION_COOKIE_SECURE", False)
    settings.CSRF_COOKIE_DOMAIN = getattr(settings, "SESSION_COOKIE_DOMAIN", None)
    settings.CSRF_COOKIE_PATH = getattr(settings, "SESSION_COOKIE_PATH", "/")

    settings.CACHES["default"]["VERSION"] = settings.CACHE_VERSION

    settings.ASSET_VERSION = get_asset_version(settings)
    settings.STATIC_URL = settings.STATIC_URL.format(version=settings.ASSET_VERSION)

    register_plugins(settings)

    initialize_receivers()

    validate_options(settings)

    if not skip_backend_validation:
        validate_backends()

    from django.utils import timezone
    from sentry.app import env
    from sentry.runner.settings import get_sentry_conf

    env.data["config"] = get_sentry_conf()
    env.data["start_date"] = timezone.now()
示例#16
0
文件: app.py 项目: faulkner/sentry
def get_instance(attribute, options, dangerous=()):
    value = getattr(settings, attribute)

    cls = import_string(value)
    if cls in dangerous:
        warnings.warn(
            warnings.UnsupportedBackend(
                u'The {!r} backend for {} is not recommended '
                'for production use.'.format(value, attribute)
            )
        )

    return cls(**options)
示例#17
0
def check_versions(service, versions, required, recommended=None):
    """
    Check that hosts fulfill version requirements.

    :param service: service label, such as ``Redis``
    :param versions: mapping of host to ``Version``
    :param required: lowest supported ``Version``. If any host does not fulfill
        this requirement, an ``InvalidConfiguration`` exception is raised.
    :param recommended: recommended version. If any host does not fulfill this
        requirement, a ``PendingDeprecationWarning`` is raised.
    """
    must_upgrade = dict(filter(lambda (host, version): required > version, versions.items()))
    if must_upgrade:
        raise InvalidConfiguration(make_upgrade_message(service, 'must', required, must_upgrade))

    if recommended:
        should_upgrade = dict(filter(lambda (host, version): recommended > version, versions.items()))
        if should_upgrade:
            warnings.warn(
                make_upgrade_message(service, 'should', recommended, should_upgrade),
                PendingDeprecationWarning,
            )
示例#18
0
def apply_legacy_settings(settings):
    from sentry import options

    # SENTRY_USE_QUEUE used to determine if Celery was eager or not
    if hasattr(settings, 'SENTRY_USE_QUEUE'):
        warnings.warn(
            DeprecatedSettingWarning(
                'SENTRY_USE_QUEUE',
                'CELERY_ALWAYS_EAGER',
                'https://docs.sentry.io/on-premise/server/queue/',
            ))
        settings.CELERY_ALWAYS_EAGER = (not settings.SENTRY_USE_QUEUE)

    for old, new in (
        ('SENTRY_ADMIN_EMAIL', 'system.admin-email'),
        ('SENTRY_URL_PREFIX', 'system.url-prefix'),
        ('SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE', 'system.rate-limit'),
        ('SENTRY_ENABLE_EMAIL_REPLIES', 'mail.enable-replies'),
        ('SENTRY_SMTP_HOSTNAME', 'mail.reply-hostname'),
        ('MAILGUN_API_KEY', 'mail.mailgun-api-key'),
    ):
        if new not in settings.SENTRY_OPTIONS and hasattr(settings, old):
            warnings.warn(
                DeprecatedSettingWarning(old, "SENTRY_OPTIONS['%s']" % new))
            settings.SENTRY_OPTIONS[new] = getattr(settings, old)

    if hasattr(settings, 'SENTRY_REDIS_OPTIONS'):
        if 'redis.clusters' in settings.SENTRY_OPTIONS:
            raise Exception(
                "Cannot specify both SENTRY_OPTIONS['redis.clusters'] option and SENTRY_REDIS_OPTIONS setting."
            )
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    'SENTRY_REDIS_OPTIONS',
                    'SENTRY_OPTIONS["redis.clusters"]',
                    removed_in_version='8.5',
                ))
            settings.SENTRY_OPTIONS['redis.clusters'] = {
                'default': settings.SENTRY_REDIS_OPTIONS,
            }
    else:
        # Provide backwards compatibility to plugins expecting there to be a
        # ``SENTRY_REDIS_OPTIONS`` setting by using the ``default`` cluster.
        # This should be removed when ``SENTRY_REDIS_OPTIONS`` is officially
        # deprecated. (This also assumes ``FLAG_NOSTORE`` on the configuration
        # option.)
        settings.SENTRY_REDIS_OPTIONS = options.get(
            'redis.clusters')['default']

    if not hasattr(settings, 'SENTRY_URL_PREFIX'):
        url_prefix = options.get('system.url-prefix', silent=True)
        if not url_prefix:
            # HACK: We need to have some value here for backwards compatibility
            url_prefix = 'http://sentry.example.com'
        settings.SENTRY_URL_PREFIX = url_prefix

    if settings.TIME_ZONE != 'UTC':
        # non-UTC timezones are not supported
        show_big_error('TIME_ZONE should be set to UTC')

    # Set ALLOWED_HOSTS if it's not already available
    if not settings.ALLOWED_HOSTS:
        settings.ALLOWED_HOSTS = ['*']

    if hasattr(settings, 'SENTRY_ALLOW_REGISTRATION'):
        warnings.warn(
            DeprecatedSettingWarning('SENTRY_ALLOW_REGISTRATION',
                                     'SENTRY_FEATURES["auth:register"]'))
        settings.SENTRY_FEATURES[
            'auth:register'] = settings.SENTRY_ALLOW_REGISTRATION

    settings.DEFAULT_FROM_EMAIL = settings.SENTRY_OPTIONS.get(
        'mail.from', settings.SENTRY_DEFAULT_OPTIONS.get('mail.from'))

    # HACK(mattrobenolt): This is a one-off assertion for a system.secret-key value.
    # If this becomes a pattern, we could add another flag to the OptionsManager to cover this, but for now
    # this is the only value that should prevent the app from booting up. Currently FLAG_REQUIRED is used to
    # trigger the Installation Wizard, not abort startup.
    if not settings.SENTRY_OPTIONS.get('system.secret-key'):
        from .importer import ConfigurationError
        raise ConfigurationError(
            "`system.secret-key` MUST be set. Use 'sentry config generate-secret-key' to get one."
        )
示例#19
0
def apply_legacy_settings(settings):
    from sentry import options

    # SENTRY_USE_QUEUE used to determine if Celery was eager or not
    if hasattr(settings, "SENTRY_USE_QUEUE"):
        warnings.warn(
            DeprecatedSettingWarning(
                "SENTRY_USE_QUEUE",
                "CELERY_ALWAYS_EAGER",
                "https://docs.sentry.io/on-premise/server/queue/",
            )
        )
        settings.CELERY_ALWAYS_EAGER = not settings.SENTRY_USE_QUEUE

    for old, new in (
        ("SENTRY_ADMIN_EMAIL", "system.admin-email"),
        ("SENTRY_URL_PREFIX", "system.url-prefix"),
        ("SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE", "system.rate-limit"),
        ("SENTRY_ENABLE_EMAIL_REPLIES", "mail.enable-replies"),
        ("SENTRY_SMTP_HOSTNAME", "mail.reply-hostname"),
        ("MAILGUN_API_KEY", "mail.mailgun-api-key"),
        ("SENTRY_FILESTORE", "filestore.backend"),
        ("SENTRY_FILESTORE_OPTIONS", "filestore.options"),
        ("GOOGLE_CLIENT_ID", "auth-google.client-id"),
        ("GOOGLE_CLIENT_SECRET", "auth-google.client-secret"),
    ):
        if new not in settings.SENTRY_OPTIONS and hasattr(settings, old):
            warnings.warn(DeprecatedSettingWarning(old, "SENTRY_OPTIONS['%s']" % new))
            settings.SENTRY_OPTIONS[new] = getattr(settings, old)

    if hasattr(settings, "SENTRY_REDIS_OPTIONS"):
        if "redis.clusters" in settings.SENTRY_OPTIONS:
            raise Exception(
                "Cannot specify both SENTRY_OPTIONS['redis.clusters'] option and SENTRY_REDIS_OPTIONS setting."
            )
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    "SENTRY_REDIS_OPTIONS",
                    'SENTRY_OPTIONS["redis.clusters"]',
                    removed_in_version="8.5",
                )
            )
            settings.SENTRY_OPTIONS["redis.clusters"] = {"default": settings.SENTRY_REDIS_OPTIONS}
    else:
        # Provide backwards compatibility to plugins expecting there to be a
        # ``SENTRY_REDIS_OPTIONS`` setting by using the ``default`` cluster.
        # This should be removed when ``SENTRY_REDIS_OPTIONS`` is officially
        # deprecated. (This also assumes ``FLAG_NOSTORE`` on the configuration
        # option.)
        settings.SENTRY_REDIS_OPTIONS = options.get("redis.clusters")["default"]

    if not hasattr(settings, "SENTRY_URL_PREFIX"):
        url_prefix = options.get("system.url-prefix", silent=True)
        if not url_prefix:
            # HACK: We need to have some value here for backwards compatibility
            url_prefix = "http://sentry.example.com"
        settings.SENTRY_URL_PREFIX = url_prefix

    if settings.TIME_ZONE != "UTC":
        # non-UTC timezones are not supported
        show_big_error("TIME_ZONE should be set to UTC")

    # Set ALLOWED_HOSTS if it's not already available
    if not settings.ALLOWED_HOSTS:
        settings.ALLOWED_HOSTS = ["*"]

    if hasattr(settings, "SENTRY_ALLOW_REGISTRATION"):
        warnings.warn(
            DeprecatedSettingWarning(
                "SENTRY_ALLOW_REGISTRATION", 'SENTRY_FEATURES["auth:register"]'
            )
        )
        settings.SENTRY_FEATURES["auth:register"] = settings.SENTRY_ALLOW_REGISTRATION

    settings.DEFAULT_FROM_EMAIL = settings.SENTRY_OPTIONS.get(
        "mail.from", settings.SENTRY_DEFAULT_OPTIONS.get("mail.from")
    )

    # HACK(mattrobenolt): This is a one-off assertion for a system.secret-key value.
    # If this becomes a pattern, we could add another flag to the OptionsManager to cover this, but for now
    # this is the only value that should prevent the app from booting up. Currently FLAG_REQUIRED is used to
    # trigger the Installation Wizard, not abort startup.
    if not settings.SENTRY_OPTIONS.get("system.secret-key"):
        from .importer import ConfigurationError

        raise ConfigurationError(
            "`system.secret-key` MUST be set. Use 'sentry config generate-secret-key' to get one."
        )
示例#20
0
def initialize_app(config, skip_service_validation=False):
    settings = config["settings"]

    bootstrap_options(settings, config["options"])

    configure_structlog()

    # Commonly setups don't correctly configure themselves for production envs
    # so lets try to provide a bit more guidance
    if settings.CELERY_ALWAYS_EAGER and not settings.DEBUG:
        warnings.warn(
            "Sentry is configured to run asynchronous tasks in-process. "
            "This is not recommended within production environments. "
            "See https://docs.sentry.io/on-premise/server/queue/ for more information."
        )

    if settings.SENTRY_SINGLE_ORGANIZATION:
        settings.SENTRY_FEATURES["organizations:create"] = False

    if not hasattr(settings, "SUDO_COOKIE_SECURE"):
        settings.SUDO_COOKIE_SECURE = getattr(settings, "SESSION_COOKIE_SECURE", False)
    if not hasattr(settings, "SUDO_COOKIE_DOMAIN"):
        settings.SUDO_COOKIE_DOMAIN = getattr(settings, "SESSION_COOKIE_DOMAIN", None)
    if not hasattr(settings, "SUDO_COOKIE_PATH"):
        settings.SUDO_COOKIE_PATH = getattr(settings, "SESSION_COOKIE_PATH", "/")

    if not hasattr(settings, "CSRF_COOKIE_SECURE"):
        settings.CSRF_COOKIE_SECURE = getattr(settings, "SESSION_COOKIE_SECURE", False)
    if not hasattr(settings, "CSRF_COOKIE_DOMAIN"):
        settings.CSRF_COOKIE_DOMAIN = getattr(settings, "SESSION_COOKIE_DOMAIN", None)
    if not hasattr(settings, "CSRF_COOKIE_PATH"):
        settings.CSRF_COOKIE_PATH = getattr(settings, "SESSION_COOKIE_PATH", "/")

    settings.CACHES["default"]["VERSION"] = settings.CACHE_VERSION

    settings.ASSET_VERSION = get_asset_version(settings)
    settings.STATIC_URL = settings.STATIC_URL.format(version=settings.ASSET_VERSION)

    if getattr(settings, "SENTRY_DEBUGGER", None) is None:
        settings.SENTRY_DEBUGGER = settings.DEBUG

    monkeypatch_model_unpickle()

    import django

    django.setup()

    monkeypatch_django_migrations()

    apply_legacy_settings(settings)

    bind_cache_to_option_store()

    register_plugins(settings)

    initialize_receivers()

    validate_options(settings)

    validate_snuba()

    configure_sdk()

    setup_services(validate=not skip_service_validation)

    from django.utils import timezone
    from sentry.app import env
    from sentry.runner.settings import get_sentry_conf

    env.data["config"] = get_sentry_conf()
    env.data["start_date"] = timezone.now()
示例#21
0
def bootstrap_options(settings, config=None):
    """
    Quickly bootstrap options that come in from a config file
    and convert options into Django settings that are
    required to even initialize the rest of the app.
    """
    # Make sure our options have gotten registered
    from sentry.options import load_defaults

    load_defaults()

    options = {}
    if config is not None:
        # Attempt to load our config yaml file
        from sentry.utils.yaml import safe_load
        from yaml.parser import ParserError
        from yaml.scanner import ScannerError

        try:
            with open(config, "rb") as fp:
                options = safe_load(fp)
        except IOError:
            # Gracefully fail if yaml file doesn't exist
            pass
        except (AttributeError, ParserError, ScannerError) as e:
            from .importer import ConfigurationError

            raise ConfigurationError("Malformed config.yml file: %s" % six.text_type(e))

        # Empty options file, so fail gracefully
        if options is None:
            options = {}
        # Options needs to be a dict
        elif not isinstance(options, dict):
            from .importer import ConfigurationError

            raise ConfigurationError("Malformed config.yml file")

    from sentry.conf.server import DEAD

    # First move options from settings into options
    for k, v in six.iteritems(options_mapper):
        if getattr(settings, v, DEAD) is not DEAD and k not in options:
            warnings.warn(DeprecatedSettingWarning(options_mapper[k], "SENTRY_OPTIONS['%s']" % k))
            options[k] = getattr(settings, v)

    # Stuff everything else into SENTRY_OPTIONS
    # these will be validated later after bootstrapping
    for k, v in six.iteritems(options):
        settings.SENTRY_OPTIONS[k] = v

    # Now go back through all of SENTRY_OPTIONS and promote
    # back into settings. This catches the case when values are defined
    # only in SENTRY_OPTIONS and no config.yml file
    for o in (settings.SENTRY_DEFAULT_OPTIONS, settings.SENTRY_OPTIONS):
        for k, v in six.iteritems(o):
            if k in options_mapper:
                # Map the mail.backend aliases to something Django understands
                if k == "mail.backend":
                    try:
                        v = settings.SENTRY_EMAIL_BACKEND_ALIASES[v]
                    except KeyError:
                        pass
                # Escalate the few needed to actually get the app bootstrapped into settings
                setattr(settings, options_mapper[k], v)
示例#22
0
def apply_legacy_settings(settings):
    from sentry import options

    # SENTRY_USE_QUEUE used to determine if Celery was eager or not
    if hasattr(settings, 'SENTRY_USE_QUEUE'):
        warnings.warn(
            DeprecatedSettingWarning(
                'SENTRY_USE_QUEUE',
                'CELERY_ALWAYS_EAGER',
                'https://docs.sentry.io/on-premise/server/queue/',
            )
        )
        settings.CELERY_ALWAYS_EAGER = (not settings.SENTRY_USE_QUEUE)

    for old, new in (
        ('SENTRY_ADMIN_EMAIL', 'system.admin-email'),
        ('SENTRY_URL_PREFIX', 'system.url-prefix'),
        ('SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE', 'system.rate-limit'),
        ('SENTRY_ENABLE_EMAIL_REPLIES', 'mail.enable-replies'),
        ('SENTRY_SMTP_HOSTNAME', 'mail.reply-hostname'),
        ('MAILGUN_API_KEY', 'mail.mailgun-api-key'),
        ('SENTRY_FILESTORE', 'filestore.backend'),
        ('SENTRY_FILESTORE_OPTIONS', 'filestore.options'),
    ):
        if new not in settings.SENTRY_OPTIONS and hasattr(settings, old):
            warnings.warn(
                DeprecatedSettingWarning(old, "SENTRY_OPTIONS['%s']" % new))
            settings.SENTRY_OPTIONS[new] = getattr(settings, old)

    if hasattr(settings, 'SENTRY_REDIS_OPTIONS'):
        if 'redis.clusters' in settings.SENTRY_OPTIONS:
            raise Exception("Cannot specify both SENTRY_OPTIONS['redis.clusters'] option and SENTRY_REDIS_OPTIONS setting.")
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    'SENTRY_REDIS_OPTIONS',
                    'SENTRY_OPTIONS["redis.clusters"]',
                    removed_in_version='8.5',
                )
            )
            settings.SENTRY_OPTIONS['redis.clusters'] = {
                'default': settings.SENTRY_REDIS_OPTIONS,
            }
    else:
        # Provide backwards compatibility to plugins expecting there to be a
        # ``SENTRY_REDIS_OPTIONS`` setting by using the ``default`` cluster.
        # This should be removed when ``SENTRY_REDIS_OPTIONS`` is officially
        # deprecated. (This also assumes ``FLAG_NOSTORE`` on the configuration
        # option.)
        settings.SENTRY_REDIS_OPTIONS = options.get('redis.clusters')['default']

    if not hasattr(settings, 'SENTRY_URL_PREFIX'):
        url_prefix = options.get('system.url-prefix', silent=True)
        if not url_prefix:
            # HACK: We need to have some value here for backwards compatibility
            url_prefix = 'http://sentry.example.com'
        settings.SENTRY_URL_PREFIX = url_prefix

    if settings.TIME_ZONE != 'UTC':
        # non-UTC timezones are not supported
        show_big_error('TIME_ZONE should be set to UTC')

    # Set ALLOWED_HOSTS if it's not already available
    if not settings.ALLOWED_HOSTS:
        settings.ALLOWED_HOSTS = ['*']

    if hasattr(settings, 'SENTRY_ALLOW_REGISTRATION'):
        warnings.warn(DeprecatedSettingWarning('SENTRY_ALLOW_REGISTRATION', 'SENTRY_FEATURES["auth:register"]'))
        settings.SENTRY_FEATURES['auth:register'] = settings.SENTRY_ALLOW_REGISTRATION

    settings.DEFAULT_FROM_EMAIL = settings.SENTRY_OPTIONS.get(
        'mail.from', settings.SENTRY_DEFAULT_OPTIONS.get('mail.from'))

    # HACK(mattrobenolt): This is a one-off assertion for a system.secret-key value.
    # If this becomes a pattern, we could add another flag to the OptionsManager to cover this, but for now
    # this is the only value that should prevent the app from booting up. Currently FLAG_REQUIRED is used to
    # trigger the Installation Wizard, not abort startup.
    if not settings.SENTRY_OPTIONS.get('system.secret-key'):
        from .importer import ConfigurationError
        raise ConfigurationError("`system.secret-key` MUST be set. Use 'sentry config generate-secret-key' to get one.")
示例#23
0
def initialize_app(config, skip_service_validation=False):
    settings = config["settings"]

    if settings.DEBUG:
        # Enable line buffering for stderr, TODO(py3.9) can be removed after py3.9, see bpo-13601
        sys.stderr = os.fdopen(sys.stderr.fileno(), "w", 1)
        sys.stdout = os.fdopen(sys.stdout.fileno(), "w", 1)

    # Just reuse the integration app for Single Org / Self-Hosted as
    # it doesn't make much sense to use 2 separate apps for SSO and
    # integration.
    if settings.SENTRY_SINGLE_ORGANIZATION:
        options_mapper.update(
            {
                "github-app.client-id": "GITHUB_APP_ID",
                "github-app.client-secret": "GITHUB_API_SECRET",
            }
        )

    bootstrap_options(settings, config["options"])

    configure_structlog()

    # Commonly setups don't correctly configure themselves for production envs
    # so lets try to provide a bit more guidance
    if settings.CELERY_ALWAYS_EAGER and not settings.DEBUG:
        warnings.warn(
            "Sentry is configured to run asynchronous tasks in-process. "
            "This is not recommended within production environments. "
            "See https://docs.sentry.io/on-premise/server/queue/ for more information."
        )

    if settings.SENTRY_SINGLE_ORGANIZATION:
        settings.SENTRY_FEATURES["organizations:create"] = False

    if not hasattr(settings, "SUDO_COOKIE_SECURE"):
        settings.SUDO_COOKIE_SECURE = getattr(settings, "SESSION_COOKIE_SECURE", False)
    if not hasattr(settings, "SUDO_COOKIE_DOMAIN"):
        settings.SUDO_COOKIE_DOMAIN = getattr(settings, "SESSION_COOKIE_DOMAIN", None)
    if not hasattr(settings, "SUDO_COOKIE_PATH"):
        settings.SUDO_COOKIE_PATH = getattr(settings, "SESSION_COOKIE_PATH", "/")

    if not hasattr(settings, "CSRF_COOKIE_SECURE"):
        settings.CSRF_COOKIE_SECURE = getattr(settings, "SESSION_COOKIE_SECURE", False)
    if not hasattr(settings, "CSRF_COOKIE_DOMAIN"):
        settings.CSRF_COOKIE_DOMAIN = getattr(settings, "SESSION_COOKIE_DOMAIN", None)
    if not hasattr(settings, "CSRF_COOKIE_PATH"):
        settings.CSRF_COOKIE_PATH = getattr(settings, "SESSION_COOKIE_PATH", "/")

    for key in settings.CACHES:
        if not hasattr(settings.CACHES[key], "VERSION"):
            settings.CACHES[key]["VERSION"] = 2

    settings.ASSET_VERSION = get_asset_version(settings)
    settings.STATIC_URL = settings.STATIC_URL.format(version=settings.ASSET_VERSION)

    if getattr(settings, "SENTRY_DEBUGGER", None) is None:
        settings.SENTRY_DEBUGGER = settings.DEBUG

    monkeypatch_model_unpickle()

    import django

    django.setup()

    monkeypatch_django_migrations()

    apply_legacy_settings(settings)

    bind_cache_to_option_store()

    register_plugins(settings)

    initialize_receivers()

    validate_options(settings)

    validate_snuba()

    configure_sdk()

    setup_services(validate=not skip_service_validation)

    from django.utils import timezone
    from sentry.app import env
    from sentry.runner.settings import get_sentry_conf

    env.data["config"] = get_sentry_conf()
    env.data["start_date"] = timezone.now()
示例#24
0
def apply_legacy_settings(settings):
    from sentry import options

    # SENTRY_USE_QUEUE used to determine if Celery was eager or not
    if hasattr(settings, 'SENTRY_USE_QUEUE'):
        warnings.warn(
            DeprecatedSettingWarning(
                'SENTRY_USE_QUEUE',
                'CELERY_ALWAYS_EAGER',
                'https://docs.getsentry.com/on-premise/server/queue/',
            )
        )
        settings.CELERY_ALWAYS_EAGER = (not settings.SENTRY_USE_QUEUE)

    for old, new in (
        ('SENTRY_ADMIN_EMAIL', 'system.admin-email'),
        ('SENTRY_URL_PREFIX', 'system.url-prefix'),
        ('SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE', 'system.rate-limit'),
    ):
        if new not in settings.SENTRY_OPTIONS and hasattr(settings, old):
            warnings.warn(
                DeprecatedSettingWarning(old, "SENTRY_OPTIONS['%s']" % new))
            settings.SENTRY_OPTIONS[new] = getattr(settings, old)

    if hasattr(settings, 'SENTRY_REDIS_OPTIONS'):
        if 'redis.clusters' in settings.SENTRY_OPTIONS:
            raise Exception("Cannot specify both SENTRY_OPTIONS['redis.clusters'] option and SENTRY_REDIS_OPTIONS setting.")
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    'SENTRY_REDIS_OPTIONS',
                    'SENTRY_OPTIONS["redis.clusters"]',
                    removed_in_version='8.5',
                )
            )
            settings.SENTRY_OPTIONS['redis.clusters'] = {
                'default': settings.SENTRY_REDIS_OPTIONS,
            }
    else:
        # Provide backwards compatibility to plugins expecting there to be a
        # ``SENTRY_REDIS_OPTIONS`` setting by using the ``default`` cluster.
        # This should be removed when ``SENTRY_REDIS_OPTIONS`` is officially
        # deprecated. (This also assumes ``FLAG_NOSTORE`` on the configuration
        # option.)
        settings.SENTRY_REDIS_OPTIONS = options.get('redis.clusters')['default']

    if not hasattr(settings, 'SENTRY_URL_PREFIX'):
        url_prefix = options.get('system.url-prefix', silent=True)
        if not url_prefix:
            # HACK: We need to have some value here for backwards compatibility
            url_prefix = 'http://sentry.example.com'
        settings.SENTRY_URL_PREFIX = url_prefix

    if settings.TIME_ZONE != 'UTC':
        # non-UTC timezones are not supported
        show_big_error('TIME_ZONE should be set to UTC')

    # Set ALLOWED_HOSTS if it's not already available
    if not settings.ALLOWED_HOSTS:
        settings.ALLOWED_HOSTS = ['*']

    if hasattr(settings, 'SENTRY_ALLOW_REGISTRATION'):
        warnings.warn(DeprecatedSettingWarning('SENTRY_ALLOW_REGISTRATION', 'SENTRY_FEATURES["auth:register"]'))
        settings.SENTRY_FEATURES['auth:register'] = settings.SENTRY_ALLOW_REGISTRATION

    settings.DEFAULT_FROM_EMAIL = settings.SENTRY_OPTIONS.get(
        'mail.from', settings.SENTRY_DEFAULT_OPTIONS.get('mail.from'))
示例#25
0
def apply_legacy_settings(settings):
    # SENTRY_USE_QUEUE used to determine if Celery was eager or not
    if hasattr(settings, 'SENTRY_USE_QUEUE'):
        warnings.warn(
            DeprecatedSettingWarning(
                'SENTRY_USE_QUEUE',
                'CELERY_ALWAYS_EAGER',
                'https://docs.getsentry.com/on-premise/server/queue/',
            ))
        settings.CELERY_ALWAYS_EAGER = (not settings.SENTRY_USE_QUEUE)

    if not settings.SENTRY_OPTIONS.get('system.admin-email') and hasattr(
            settings, 'SENTRY_ADMIN_EMAIL'):
        warnings.warn(
            DeprecatedSettingWarning('SENTRY_ADMIN_EMAIL',
                                     'SENTRY_OPTIONS["system.admin-email"]'))
        settings.SENTRY_OPTIONS[
            'system.admin-email'] = settings.SENTRY_ADMIN_EMAIL

    if not settings.SENTRY_OPTIONS.get('system.url-prefix') and hasattr(
            settings, 'SENTRY_URL_PREFIX'):
        warnings.warn(
            DeprecatedSettingWarning('SENTRY_URL_PREFIX',
                                     'SENTRY_OPTIONS["system.url-prefix"]'))
        settings.SENTRY_OPTIONS[
            'system.url-prefix'] = settings.SENTRY_URL_PREFIX

    if not settings.SENTRY_OPTIONS.get('system.rate-limit') and hasattr(
            settings, 'SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE'):
        warnings.warn(
            DeprecatedSettingWarning('SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE',
                                     'SENTRY_OPTIONS["system.rate-limit"]'))
        settings.SENTRY_OPTIONS[
            'system.rate-limit'] = settings.SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE

    if hasattr(settings, 'SENTRY_REDIS_OPTIONS'):
        if 'redis.clusters' in settings.SENTRY_OPTIONS:
            raise Exception(
                "Cannot specify both SENTRY_OPTIONS['redis.clusters'] option and SENTRY_REDIS_OPTIONS setting."
            )
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    'SENTRY_REDIS_OPTIONS',
                    'SENTRY_OPTIONS["redis.clusters"]',
                    removed_in_version='8.5',
                ))
            settings.SENTRY_OPTIONS['redis.clusters'] = {
                'default': settings.SENTRY_REDIS_OPTIONS,
            }
    else:
        # Provide backwards compatibility to plugins expecting there to be a
        # ``SENTRY_REDIS_OPTIONS`` setting by using the ``default`` cluster.
        # This should be removed when ``SENTRY_REDIS_OPTIONS`` is officially
        # deprecated. (This also assumes ``FLAG_NOSTORE`` on the configuration
        # option.)
        from sentry import options
        settings.SENTRY_REDIS_OPTIONS = options.get(
            'redis.clusters')['default']

    if not hasattr(settings, 'SENTRY_URL_PREFIX'):
        from sentry import options
        url_prefix = options.get('system.url-prefix', silent=True)
        if not url_prefix:
            # HACK: We need to have some value here for backwards compatibility
            url_prefix = 'http://sentry.example.com'
        settings.SENTRY_URL_PREFIX = url_prefix

    if settings.TIME_ZONE != 'UTC':
        # non-UTC timezones are not supported
        show_big_error('TIME_ZONE should be set to UTC')

    # Set ALLOWED_HOSTS if it's not already available
    if not settings.ALLOWED_HOSTS:
        from .hacks import AllowedHosts
        settings.ALLOWED_HOSTS = AllowedHosts()

    if hasattr(settings, 'SENTRY_ALLOW_REGISTRATION'):
        warnings.warn(
            DeprecatedSettingWarning('SENTRY_ALLOW_REGISTRATION',
                                     'SENTRY_FEATURES["auth:register"]'))
        settings.SENTRY_FEATURES[
            'auth:register'] = settings.SENTRY_ALLOW_REGISTRATION
示例#26
0
def initialize_app(config, skip_service_validation=False):
    settings = config['settings']

    bootstrap_options(settings, config['options'])

    from clims.logs import configure_logging
    configure_logging()

    if 'south' in settings.INSTALLED_APPS:
        fix_south(settings)

    # Commonly setups don't correctly configure themselves for production envs
    # so lets try to provide a bit more guidance
    if settings.CELERY_ALWAYS_EAGER and not settings.DEBUG:
        warnings.warn(
            'Sentry is configured to run asynchronous tasks in-process. '
            'This is not recommended within production environments. '
            'See https://docs.sentry.io/on-premise/server/queue/ for more information.'
        )

    if settings.SENTRY_SINGLE_ORGANIZATION:
        settings.SENTRY_FEATURES['organizations:create'] = False

    if not hasattr(settings, 'SUDO_COOKIE_SECURE'):
        settings.SUDO_COOKIE_SECURE = getattr(settings,
                                              'SESSION_COOKIE_SECURE', False)
    if not hasattr(settings, 'SUDO_COOKIE_DOMAIN'):
        settings.SUDO_COOKIE_DOMAIN = getattr(settings,
                                              'SESSION_COOKIE_DOMAIN', None)
    if not hasattr(settings, 'SUDO_COOKIE_PATH'):
        settings.SUDO_COOKIE_PATH = getattr(settings, 'SESSION_COOKIE_PATH',
                                            '/')

    if not hasattr(settings, 'CSRF_COOKIE_SECURE'):
        settings.CSRF_COOKIE_SECURE = getattr(settings,
                                              'SESSION_COOKIE_SECURE', False)
    if not hasattr(settings, 'CSRF_COOKIE_DOMAIN'):
        settings.CSRF_COOKIE_DOMAIN = getattr(settings,
                                              'SESSION_COOKIE_DOMAIN', None)
    if not hasattr(settings, 'CSRF_COOKIE_PATH'):
        settings.CSRF_COOKIE_PATH = getattr(settings, 'SESSION_COOKIE_PATH',
                                            '/')

    settings.CACHES['default']['VERSION'] = settings.CACHE_VERSION

    settings.ASSET_VERSION = get_asset_version(settings)
    settings.STATIC_URL = settings.STATIC_URL.format(
        version=settings.ASSET_VERSION, )

    import django
    django.setup()

    bind_cache_to_option_store()

    from clims.services.application import ioc, ApplicationService
    app = ApplicationService()
    ioc.set_application(app)
    app.plugins.load_installed()

    initialize_receivers()

    validate_options(settings)

    setup_services(validate=not skip_service_validation)

    from django.utils import timezone
    from sentry.app import env
    from sentry.runner.settings import get_sentry_conf
    env.data['config'] = get_sentry_conf()
    env.data['start_date'] = timezone.now()
示例#27
0
def apply_legacy_settings(settings):
    from sentry import options

    # SENTRY_USE_QUEUE used to determine if Celery was eager or not
    if hasattr(settings, "SENTRY_USE_QUEUE"):
        warnings.warn(
            DeprecatedSettingWarning(
                "SENTRY_USE_QUEUE", "CELERY_ALWAYS_EAGER", "https://docs.getsentry.com/on-premise/server/queue/"
            )
        )
        settings.CELERY_ALWAYS_EAGER = not settings.SENTRY_USE_QUEUE

    for old, new in (
        ("SENTRY_ADMIN_EMAIL", "system.admin-email"),
        ("SENTRY_URL_PREFIX", "system.url-prefix"),
        ("SENTRY_SYSTEM_MAX_EVENTS_PER_MINUTE", "system.rate-limit"),
        ("SENTRY_ENABLE_EMAIL_REPLIES", "mail.enable-replies"),
        ("SENTRY_SMTP_HOSTNAME", "mail.reply-hostname"),
        ("MAILGUN_API_KEY", "mail.mailgun-api-key"),
    ):
        if new not in settings.SENTRY_OPTIONS and hasattr(settings, old):
            warnings.warn(DeprecatedSettingWarning(old, "SENTRY_OPTIONS['%s']" % new))
            settings.SENTRY_OPTIONS[new] = getattr(settings, old)

    if hasattr(settings, "SENTRY_REDIS_OPTIONS"):
        if "redis.clusters" in settings.SENTRY_OPTIONS:
            raise Exception(
                "Cannot specify both SENTRY_OPTIONS['redis.clusters'] option and SENTRY_REDIS_OPTIONS setting."
            )
        else:
            warnings.warn(
                DeprecatedSettingWarning(
                    "SENTRY_REDIS_OPTIONS", 'SENTRY_OPTIONS["redis.clusters"]', removed_in_version="8.5"
                )
            )
            settings.SENTRY_OPTIONS["redis.clusters"] = {"default": settings.SENTRY_REDIS_OPTIONS}
    else:
        # Provide backwards compatibility to plugins expecting there to be a
        # ``SENTRY_REDIS_OPTIONS`` setting by using the ``default`` cluster.
        # This should be removed when ``SENTRY_REDIS_OPTIONS`` is officially
        # deprecated. (This also assumes ``FLAG_NOSTORE`` on the configuration
        # option.)
        settings.SENTRY_REDIS_OPTIONS = options.get("redis.clusters")["default"]

    if not hasattr(settings, "SENTRY_URL_PREFIX"):
        url_prefix = options.get("system.url-prefix", silent=True)
        if not url_prefix:
            # HACK: We need to have some value here for backwards compatibility
            url_prefix = "http://sentry.example.com"
        settings.SENTRY_URL_PREFIX = url_prefix

    if settings.TIME_ZONE != "UTC":
        # non-UTC timezones are not supported
        show_big_error("TIME_ZONE should be set to UTC")

    # Set ALLOWED_HOSTS if it's not already available
    if not settings.ALLOWED_HOSTS:
        settings.ALLOWED_HOSTS = ["*"]

    if hasattr(settings, "SENTRY_ALLOW_REGISTRATION"):
        warnings.warn(DeprecatedSettingWarning("SENTRY_ALLOW_REGISTRATION", 'SENTRY_FEATURES["auth:register"]'))
        settings.SENTRY_FEATURES["auth:register"] = settings.SENTRY_ALLOW_REGISTRATION

    settings.DEFAULT_FROM_EMAIL = settings.SENTRY_OPTIONS.get(
        "mail.from", settings.SENTRY_DEFAULT_OPTIONS.get("mail.from")
    )