}, 'django.security.DisallowedHost': { # Don't log attempts to access the site with a spoofed HTTP-HOST header. It massively clutters the logs, # and we really don't care about this error. 'handlers': ['null'], 'propagate': False, }, }, 'root': { # Set up the root logger to print to stdout. 'handlers': ['console'], 'level': 'INFO', }, 'formatters': { 'plain': { '()': structlog.stdlib.ProcessorFormatter, 'processor': ConsoleRenderer(colors=getenv('COLORED_LOGGING', False), repr_native_str=False, newlines=True), 'foreign_pre_chain': pre_chain, 'format': 'SYSLOG %(message)s' } }, } RAVEN_CONFIG = {'dsn': getenv('SENTRY_DSN', None)}
from djunk.utils import getenv # General settings. bind = '0.0.0.0:9300' workers = 8 worker_class = 'sync' daemon = False timeout = 300 # requires futures module for threads > 1. threads = 1 # During development, this will cause the server to reload when the code changes. # noinspection PyShadowingBuiltins reload = getenv('GUNICORN_RELOAD', False) # If remote debugging is enabled set the timeout very high, so one can pause for a long time in the debugger. # Also set the number of workers to 1, which improves the debugging experience by not overwhleming the remote debugger. if getenv('REMOTE_DEBUG_ENABLED', False): timeout = 9999 workers = 1 # Logging. accesslog = '-' access_log_format = '%({X-Forwarded-For}i)s %(l)s %(u)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s' errorlog = '-' syslog = False # statsd settings need to have defaults provided, because dev sites don't use statsd. host = getenv('STATSD_HOST', None) port = getenv('STATSD_PORT', 8125)
################################################################# # Multitenant Config ################################################################# from djunk.utils import getenv # Defines the base domain for all Sites on this server. e.g. 'oursites.com' SERVER_DOMAIN = getenv('SERVER_DOMAIN') # Specify the prefixes for paths that NEED to end in slash, so that SlashMiddleware can redirect us to them from their # slashless versions. e.g. going to /admin/login will redirect to /admin/login/ SLASHED_PATHS = ['/admin', '/django-admin']
""" WSGI config for multitenant project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ """ import os from django.core.wsgi import get_wsgi_application from djunk.utils import getenv os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'multitenant.settings.settings') # If the environment is configured to enable remote debugging, attach to the configured remote debug server. # If REMOTE_DEBUG_ENABLED set to True, REMOTE_DEBUG_HOST and REMOTE_DEBUG_PORT are required. if getenv('REMOTE_DEBUG_ENABLED', False): # We keep this import inside the REMOTE_DEBUG_ENABLED check because simply doing the import slows down the process, # even if we don't call settrace(). print("Debugging Enabled") import pydevd # Attach to a Remote Debugger session running in PyCharm or PyDev on the configured host and port. # NOTE: If no remote debug server is running, this call will hang indefinitely. Be aware of this! pydevd.settrace(host=getenv('REMOTE_DEBUG_HOST'), port=getenv('REMOTE_DEBUG_PORT'), suspend=False) application = get_wsgi_application()
################################################################# # Cache Config ################################################################# from djunk.utils import getenv CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://{}:6379'.format(getenv('CACHE')), 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient' }, 'KEY_PREFIX': 'oursites', } } # Config for django-cacheops. CACHEOPS_ENABLED = True CACHEOPS_REDIS = 'redis://{}:6379/2'.format(getenv('CACHE')) CACHEOPS = { 'auth.user': {'ops': 'get', 'timeout': 60*15}, # Automatically cache all gets and queryset fetches to other django.contrib.auth models for an hour 'auth.*': {'ops': ('fetch', 'get'), 'timeout': 60*60}, # Cache all queries to Permission # 'all' is just an alias for {'get', 'fetch', 'count', 'aggregate', 'exists'} 'auth.permission': {'ops': 'all', 'timeout': 60*60}, '*.*': {'timeout': 60*60}, } # Disable all caching if the optional DISABLE_CACHE env var is True. if getenv('DISABLE_CACHE', False):
################################################################# # Django Config ################################################################# import os from djunk.utils import getenv SETTINGS_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) PROJECT_DIR = os.path.dirname(SETTINGS_DIR) BASE_DIR = os.path.dirname(PROJECT_DIR) DEBUG = getenv('DEBUG', False) INSTALLED_APPS = [ 'our_sites', # Multitenant apps. 'core', 'search', 'site_creator', 'theme', 'robots_txt', 'wagtail_patches', 'sitemap', 'features', # Multitenant dependencies. 'jetstream', 'djunk', 'suit', 'suit_ckeditor', 'storages',
################################################################# # Development Config ################################################################# from djunk.utils import install_if_available, getenv from .django import PROJECT_DIR, INSTALLED_APPS, TEMPLATES, MIDDLEWARE from .logging import LOGGING from .wagtail import WAGTAILSEARCH_BACKENDS if getenv('DEVELOPMENT', False): # Useful info for syling custom admin pages. Not helpful to site users, though. Just developers. # NOTE: The static resources for this app will not be collected during docker image creation, because DEVELOPMENT # isn't true at that time. To get styleguide.css into place, run collectstatic manually in your dev container. INSTALLED_APPS.append('wagtail.contrib.wagtailstyleguide') # Don't send real emails during developmnent. Just print them to the console. EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # Don't validate passwords during development. Our rules make for hard-to-remember passwords. AUTH_PASSWORD_VALIDATORS = [] # Don't use Sentry during development. INSTALLED_APPS.remove('raven.contrib.django.raven_compat') SERVER_EMAIL = DEFAULT_FROM_ADDRESS = WAGTAILADMIN_NOTIFICATION_FROM_EMAIL = '*****@*****.**' EMAIL_SUBJECT_PREFIX = '[oursites-dev] ' # Django uses cached template loading by default, so we need to disable that during development or you won't # see any of the edits you make to templates. However, with template caching disabled, FlexPage forms load # extremely slowly. If you are actively using the FlexPage editor and can't stand 45+ second load times, # comment out the two TEMPLATES settings below. # NOTE: We have to set APP_DIRS=False because Django won't let us use 'APP_DIRS' and 'loaders' together. TEMPLATES[0]['APP_DIRS'] = False TEMPLATES[0]['OPTIONS']['loaders'] = [ 'django.template.loaders.filesystem.Loader',
import ldap from djunk.utils import getenv from django_auth_ldap.config import LDAPSearch ################################################################# # django-auth-ldap Config ################################################################# AUTH_LDAP_SERVER_URI = getenv('LDAP_URL') AUTH_LDAP_BIND_DN = getenv('LDAP_USER') AUTH_LDAP_BIND_PASSWORD = getenv('LDAP_PASSWORD') AUTH_LDAP_START_TLS = True AUTH_LDAP_USER_SEARCH = LDAPSearch(getenv('LDAP_BASE_PEOPLE_DN'), ldap.SCOPE_SUBTREE, "(uid=%(user)s)") ################################################################# # django-auth password validator config ################################################################# AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 'OPTIONS': { 'user_attributes': ['username', 'first_name', 'last_name', 'email'] } }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'OPTIONS': { 'min_length': 10, } }, { 'NAME': 'core.validators.LocalUserPasswordValidator',
from djunk.utils import getenv ################################################################# # django-storages Config ################################################################# # Use our subclass of S3Boto3Storage. AWS_S3_REGION_NAME = getenv('AWS_DEFAULT_REGION', 'us-west-2') AWS_STORAGE_BUCKET_NAME = getenv('AWS_STORAGE_BUCKET_NAME') AWS_S3_FILE_OVERWRITE = False # These credentials aren't used in test/prod; the IAM role is used instead. So they're allowed to not be set. AWS_ACCESS_KEY_ID = getenv('AWS_ACCESS_KEY_ID', None) AWS_SECRET_ACCESS_KEY = getenv('AWS_SECRET_ACCESS_KEY', None) AWS_DEFAULT_ACL = 'public-read'
# Celery Config ################################################################# from __future__ import absolute_import import structlog from celery.schedules import crontab from celery.signals import after_setup_logger from djunk.utils import getenv from djunk.logging_handlers import ConsoleRenderer from multitenant.settings.sections.logging import pre_chain # When we're in the cloud (so that logstash can correctly group all the # exception lines into one message), we modify the syslog formatter class. # We'll know we're in the cloud beause deployfish will inject the # DEPLOYFISH_SERVICE_NAME environment variable into our task configuraiton # environment newlines = getenv('DEPLOYFISH_SERVICE_NAME', None) is None colors = getenv('COLORED_LOGGING', False) # Like in logging.py, use struclog to handle our Celery log messages so we can add context to # each message in a sane way. @after_setup_logger.connect() def logger_setup_handler(logger, **kwargs): for handler in logger.handlers: my_formatter = structlog.stdlib.ProcessorFormatter( ConsoleRenderer(colors=colors, repr_native_str=True, newlines=newlines), fmt='SYSLOG %(message)s', foreign_pre_chain=pre_chain) handler.setFormatter(my_formatter)
################################################################# # Wagtail Config ################################################################# from djunk.utils import getenv # Display usage count on an image's edit page. WAGTAIL_USAGE_COUNT_ENABLED = True # Don't forcibly append slashes to the ends of URLs. Users can still reach each URL with a trailing slash, but it's # not needed, and no redirects will be issued just to add a useless trailing slash. WAGTAIL_APPEND_SLASH = False APPEND_SLASH = False # Elasticsearch WAGTAILSEARCH_BACKENDS = { 'default': { 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch5', 'URLS': getenv('WAGTAIL_ELASTICSEARCH_URL').split(','), 'INDEX': 'wagtail-multi', 'TIMEOUT': 120, 'ATOMIC_REBUILD': True, } } WAGTAIL_SITE_NAME = 'Our Sites' WAGTAILIMAGES_IMAGE_MODEL = 'core.OurImage' WAGTAILIMAGES_MAX_UPLOAD_SIZE = 30 * 1024 * 1024 # 30MB WAGTAILDOCS_DOCUMENT_MODEL = 'our_sites.PermissionedDocument'
################################################################# # Database Config ################################################################# from djunk.utils import getenv DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': getenv('DB_NAME'), 'HOST': getenv('DB_HOST'), 'PORT': getenv('DB_PORT'), 'USER': getenv('DB_USER'), 'PASSWORD': getenv('DB_PASSWORD'), 'OPTIONS': { 'sql_mode': 'ANSI,STRICT_TRANS_TABLES', } }, }