Use MIDDLEWARE with adapted old-style middleware, the template context processors, explicit bootstrap3 URLs, the captcha app name, and drop the obsolete migration module overrides and removed apps.
763 lines
22 KiB
Python
763 lines
22 KiB
Python
"""
|
|
Copyright 2015 ungleich.
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
# -*- coding: utf-8 -*-
|
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
|
import os
|
|
|
|
# dotenv
|
|
import dotenv
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def gettext(s):
|
|
return s
|
|
|
|
|
|
def env(env_name, default=None):
|
|
"""Returns the environment value, or default if it is unset or empty"""
|
|
value = os.environ.get(env_name)
|
|
return default if value is None or value == '' else value
|
|
|
|
|
|
def bool_env(val):
|
|
"""Replaces string based environment values with Python booleans"""
|
|
return True if os.environ.get(val, False) == 'True' else False
|
|
|
|
|
|
def int_env(val, default_value=0):
|
|
"""Replaces string based environment values with Python integers
|
|
Return default_value if val is not set or cannot be parsed, otherwise
|
|
returns the python integer equal to the passed val
|
|
"""
|
|
return_value = default_value
|
|
try:
|
|
return_value = int(os.environ.get(val))
|
|
except Exception as e:
|
|
logger.error(
|
|
("Encountered exception trying to get env value for {}\nException "
|
|
"details: {}").format(
|
|
val, str(e)))
|
|
|
|
return return_value
|
|
|
|
|
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
PROJECT_DIR = os.path.abspath(
|
|
os.path.join(os.path.dirname(__file__), "../.."),
|
|
)
|
|
|
|
# load .env file
|
|
dotenv.load_dotenv("{0}/.env".format(PROJECT_DIR))
|
|
|
|
from multisite import SiteID
|
|
|
|
RECAPTCHA_PUBLIC_KEY = env('RECAPTCHA_PUBLIC_KEY')
|
|
RECAPTCHA_PRIVATE_KEY = env('RECAPTCHA_PRIVATE_KEY')
|
|
|
|
UNGLEICH_BLOG_SITE_ID = int_env("UNGLEICH_BLOG_SITE_ID")
|
|
SITE_ID = SiteID(default=(UNGLEICH_BLOG_SITE_ID if
|
|
UNGLEICH_BLOG_SITE_ID > 0 else 1))
|
|
|
|
APP_ROOT_ENDPOINT = "/"
|
|
APPEND_SLASH = True
|
|
|
|
LOGIN_URL = None
|
|
LOGOUT_URL = None
|
|
LOGIN_REDIRECT_URL = None
|
|
|
|
EMAIL_HOST = env("EMAIL_HOST")
|
|
if not EMAIL_HOST:
|
|
EMAIL_HOST = "localhost"
|
|
EMAIL_PORT = int_env("EMAIL_PORT", 25)
|
|
EMAIL_USE_TLS = bool_env("EMAIL_USE_TLS")
|
|
|
|
SECRET_KEY = env('DJANGO_SECRET_KEY')
|
|
if not SECRET_KEY:
|
|
# the docker entrypoint persists a generated key here; this lets
|
|
# "docker compose exec" commands, which skip the entrypoint, find it
|
|
_key_file = env('SECRET_KEY_FILE', '/data/secret-key')
|
|
if os.path.exists(_key_file):
|
|
with open(_key_file) as _f:
|
|
SECRET_KEY = _f.read().strip()
|
|
|
|
# Application definition
|
|
|
|
INSTALLED_APPS = (
|
|
# 1st migrate
|
|
'membership',
|
|
'djangocms_admin_style',
|
|
'django.contrib.admin',
|
|
'django.contrib.auth',
|
|
'django.contrib.contenttypes',
|
|
'django.contrib.humanize',
|
|
'django.contrib.sessions',
|
|
'django.contrib.messages',
|
|
'django.contrib.staticfiles',
|
|
'django.contrib.sites',
|
|
'multisite',
|
|
'djangocms_multisite',
|
|
'easy_thumbnails',
|
|
'utils',
|
|
'stored_messages',
|
|
'mptt',
|
|
'parler',
|
|
'guardian',
|
|
'taggit',
|
|
'taggit_autosuggest',
|
|
# 'django_select2',
|
|
'meta',
|
|
'bootstrap3',
|
|
'compressor',
|
|
'filer',
|
|
'djangocms_blog',
|
|
'cms', # django CMS itself
|
|
'aldryn_apphooks_config',
|
|
'aldryn_boilerplates',
|
|
'aldryn_categories',
|
|
'aldryn_common',
|
|
'aldryn_newsblog',
|
|
'aldryn_people',
|
|
'aldryn_translation_tools',
|
|
'treebeard', # utilities for implementing a tree
|
|
'sekizai', # for javascript and css management
|
|
'menus', # helper for model independent hierarchical website navigation
|
|
'cmsplugin_filer_image',
|
|
|
|
# 2nd migrate
|
|
# django-cms plugins
|
|
'djangocms_file',
|
|
'djangocms_picture',
|
|
'djangocms_video',
|
|
'captcha',
|
|
# 'djangocms_flash',
|
|
# 'djangocms_googlemap',
|
|
# 'djangocms_inherit',
|
|
# 'djangocms_link',
|
|
# 'djangocms_teaser',
|
|
'djangocms_page_meta',
|
|
'djangocms_text_ckeditor',
|
|
'cmsplugin_filer_file',
|
|
'cmsplugin_filer_folder',
|
|
'cmsplugin_filer_link',
|
|
# 'cmsplugin_filer_teaser',
|
|
'cmsplugin_filer_video',
|
|
#
|
|
# blog
|
|
# versioning
|
|
'reversion',
|
|
# ungleich
|
|
'ungleich',
|
|
'ungleich_page',
|
|
'hosting',
|
|
'digitalglarus',
|
|
'nosystemd',
|
|
'datacenterlight',
|
|
# 'datacenterlight.templatetags',
|
|
'alplora',
|
|
'rest_framework',
|
|
'opennebula_api',
|
|
'django_celery_results',
|
|
'webhook',
|
|
)
|
|
|
|
MIDDLEWARE = (
|
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
'utils.middleware.MultipleProxyMiddleware',
|
|
'django.middleware.common.CommonMiddleware',
|
|
'django.middleware.csrf.CsrfViewMiddleware',
|
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
'django.contrib.messages.middleware.MessageMiddleware',
|
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
'django.middleware.locale.LocaleMiddleware',
|
|
# django-cms middlewares
|
|
'cms.middleware.user.CurrentUserMiddleware',
|
|
'cms.middleware.page.CurrentPageMiddleware',
|
|
'cms.middleware.toolbar.ToolbarMiddleware',
|
|
'cms.middleware.language.LanguageCookieMiddleware',
|
|
'multisite.middleware.DynamicSiteMiddleware',
|
|
'utils.middleware.CMSMultiSiteMiddleware',
|
|
)
|
|
|
|
CSRF_FAILURE_VIEW = 'hosting.views.forbidden_view'
|
|
|
|
ROOT_URLCONF = 'dynamicweb.urls'
|
|
|
|
TEMPLATES = [
|
|
{
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
'DIRS': [os.path.join(PROJECT_DIR, 'membership'),
|
|
os.path.join(PROJECT_DIR, 'hosting/templates/'),
|
|
os.path.join(PROJECT_DIR, 'nosystemd/templates/'),
|
|
os.path.join(PROJECT_DIR,
|
|
'ungleich/templates/djangocms_blog/'),
|
|
os.path.join(PROJECT_DIR,
|
|
'ungleich/templates/cms/ungleichch'),
|
|
os.path.join(PROJECT_DIR, 'ungleich/templates/ungleich'),
|
|
os.path.join(PROJECT_DIR,
|
|
'ungleich_page/templates/ungleich_page'),
|
|
os.path.join(PROJECT_DIR, 'templates/analytics'),
|
|
os.path.join(PROJECT_DIR, 'cms_templates/'),
|
|
os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'),
|
|
os.path.join(PROJECT_DIR, 'templates/gdpr'),
|
|
],
|
|
'APP_DIRS': True,
|
|
'OPTIONS': {
|
|
'context_processors': [
|
|
'django.template.context_processors.debug',
|
|
'django.template.context_processors.request',
|
|
'django.contrib.auth.context_processors.auth',
|
|
'django.contrib.messages.context_processors.messages',
|
|
"django.template.context_processors.media",
|
|
"django.template.context_processors.static",
|
|
"django.template.context_processors.tz",
|
|
"django.contrib.messages.context_processors.messages",
|
|
'sekizai.context_processors.sekizai',
|
|
'cms.context_processors.cms_settings',
|
|
'utils.context_processor.google_analytics',
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
WSGI_APPLICATION = 'dynamicweb.wsgi.application'
|
|
|
|
CMS_TEMPLATES = (
|
|
('base_glarus.html', gettext('default')),
|
|
('one_column.html', gettext('2 Column')),
|
|
('two_columns.html', gettext('3 Column')),
|
|
('about.html', gettext('DG.About')),
|
|
('contact.html', gettext('DG.Contact')),
|
|
('home_digitalglarus.html', gettext('DG.Home')),
|
|
('letscowork.html', gettext('DG.CoWork')),
|
|
# ('detail.html', gettext('DG.Detail')),
|
|
('one_column.html', gettext('DG.OneColumn')),
|
|
# ungleich
|
|
('blog_ungleich.html', gettext('Blog')),
|
|
('page.html', gettext('Page')),
|
|
# dcl
|
|
('datacenterlight/cms/base.html', gettext('Data Center Light')),
|
|
('ungleich_page/glasfaser_cms_page.html', gettext('Glasfaser')),
|
|
('ungleich_page/ungleich_cms_page.html', gettext('ungleich')),
|
|
)
|
|
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
|
'NAME': 'app',
|
|
}
|
|
}
|
|
|
|
AUTHENTICATION_BACKENDS = (
|
|
'utils.backend.MyLDAPBackend',
|
|
'guardian.backends.ObjectPermissionBackend',
|
|
|
|
)
|
|
|
|
# Internationalization
|
|
# https://docs.djangoproject.com/en/1.7/topics/i18n/
|
|
|
|
TIME_ZONE = 'UTC'
|
|
|
|
USE_I18N = True
|
|
|
|
USE_L10N = True
|
|
|
|
USE_TZ = True
|
|
|
|
FORMAT_MODULE_PATH = [
|
|
'dynamicweb.formats'
|
|
]
|
|
|
|
LANGUAGES = (
|
|
('en-us', _('English')),
|
|
('de', _('Deutsch')),
|
|
)
|
|
|
|
LANGUAGE_CODE = 'en-us'
|
|
|
|
LOCALE_PATHS = [
|
|
os.path.join(PROJECT_DIR, 'digitalglarus/locale'),
|
|
]
|
|
|
|
CMS_PLACEHOLDER_CONF = {
|
|
'logo_image': {
|
|
'name': 'Logo Image',
|
|
'plugins': ['FilerImagePlugin'],
|
|
'limits': {
|
|
'global': 1,
|
|
}
|
|
},
|
|
'page-title': {
|
|
'name': 'Page Title',
|
|
'plugins': ['TextPlugin'],
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'TextPlugin',
|
|
'values': {
|
|
'body': 'Page Title...'
|
|
}
|
|
}
|
|
],
|
|
'limits': {
|
|
'global': 1,
|
|
}
|
|
},
|
|
'page-subtitle': {
|
|
'name': 'Page Subtitle',
|
|
'inherit': 'page-title',
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'TextPlugin',
|
|
'values': {
|
|
'body': 'Page subtitle...'
|
|
}
|
|
}
|
|
],
|
|
},
|
|
'footer_copyright': {
|
|
'name': 'Copyright',
|
|
'inherit': 'page-title',
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'TextPlugin',
|
|
'values': {
|
|
'body': 'Copyright...'
|
|
}
|
|
}
|
|
],
|
|
},
|
|
'content': {
|
|
'name': _('Content'),
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'TextPlugin',
|
|
'values': {'body': '<p></p>'},
|
|
},
|
|
]
|
|
},
|
|
'post_content': {
|
|
'name': _('Content'),
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'TextPlugin',
|
|
'values': {'body': '<p></p>'},
|
|
},
|
|
]
|
|
},
|
|
'datacenterlight_navbar': {
|
|
'name': _('Datacenterlight Navbar'),
|
|
'plugins': ['DCLNavbarPlugin'],
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'DCLNavbarPlugin',
|
|
'values': {},
|
|
},
|
|
]
|
|
},
|
|
'datacenterlight_footer': {
|
|
'name': _('Datacenterlight Footer'),
|
|
'plugins': ['DCLFooterPlugin'],
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'DCLFooterPlugin',
|
|
'values': {},
|
|
},
|
|
]
|
|
},
|
|
'datacenterlight_calculator': {
|
|
'name': _('Datacenterlight Calculator'),
|
|
'plugins': ['DCLCalculatorPlugin'],
|
|
'default_plugins': [
|
|
{
|
|
'plugin_type': 'DCLCalculatorPlugin',
|
|
'values': {
|
|
'pricing_id': 1
|
|
},
|
|
},
|
|
]
|
|
},
|
|
}
|
|
|
|
CMS_PERMISSION = True
|
|
|
|
CACHES = {
|
|
'default': {
|
|
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
|
|
'LOCATION': '127.0.0.1:11211',
|
|
}
|
|
}
|
|
|
|
if LOGIN_URL is None:
|
|
LOGIN_URL = APP_ROOT_ENDPOINT + 'login/'
|
|
if LOGOUT_URL is None:
|
|
LOGOUT_URL = APP_ROOT_ENDPOINT + 'logout/'
|
|
if LOGIN_REDIRECT_URL is None:
|
|
LOGIN_REDIRECT_URL = APP_ROOT_ENDPOINT
|
|
|
|
# Static files (CSS, JavaScript, Images)
|
|
# https://docs.djangoproject.com/en/1.7/howto/static-files/
|
|
|
|
STATIC_URL = '/static/'
|
|
|
|
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
|
|
|
|
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media')
|
|
MEDIA_URL = APP_ROOT_ENDPOINT + 'media/'
|
|
FILE_UPLOAD_PERMISSIONS = 0o644
|
|
|
|
STATICFILES_FINDERS = (
|
|
'django.contrib.staticfiles.finders.FileSystemFinder',
|
|
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
|
'compressor.finders.CompressorFinder',
|
|
)
|
|
|
|
# COMPRESS_PRECOMPILERS = (
|
|
# ('text/less', 'lesscpy {infile}'),
|
|
# )
|
|
|
|
THUMBNAIL_PROCESSORS = (
|
|
'easy_thumbnails.processors.colorspace',
|
|
'easy_thumbnails.processors.autocrop',
|
|
'filer.thumbnail_processors.scale_and_crop_with_subject_location',
|
|
'easy_thumbnails.processors.filters',
|
|
)
|
|
|
|
# django-cms-text-ckeditor
|
|
TEXT_SAVE_IMAGE_FUNCTION = (
|
|
'cmsplugin_filer_image.integrations.ckeditor.create_image_plugin'
|
|
)
|
|
TEXT_ADDITIONAL_TAGS = ('iframe',)
|
|
TEXT_ADDITIONAL_ATTRIBUTES = ('scrolling', 'allowfullscreen', 'frameborder')
|
|
USE_X_FORWARDED_HOST = True
|
|
|
|
# Django Bootstrap - Settings
|
|
# Added Configuration for bootstrap static files to load over https.
|
|
BOOTSTRAP3 = {
|
|
|
|
# The URL to the jQuery JavaScript file
|
|
'jquery_url': '%sdatacenterlight/js/jquery-1.11.1.min.js' % STATIC_URL,
|
|
|
|
# The complete URL to the Bootstrap CSS file
|
|
'css_url': '%sdatacenterlight/bootstrap-3.3.4/css/bootstrap.min.css' % STATIC_URL,
|
|
|
|
# The complete URL to the Bootstrap CSS file (None means no theme)
|
|
'theme_url': None,
|
|
|
|
# The complete URL to the Bootstrap JavaScript file
|
|
'javascript_url': '%sdatacenterlight/bootstrap-3.3.4/js/bootstrap.min.js' % STATIC_URL,
|
|
|
|
# Put JavaScript in the HEAD section of the HTML document
|
|
# (only relevant if you use bootstrap3.html)
|
|
'javascript_in_head': False,
|
|
|
|
# Include jQuery with Bootstrap JavaScript
|
|
# (affects django-bootstrap3 template tags)
|
|
'include_jquery': False,
|
|
|
|
# Label class to use in horizontal forms
|
|
'horizontal_label_class': 'col-md-3',
|
|
|
|
# Field class to use in horizontal forms
|
|
'horizontal_field_class': 'col-md-9',
|
|
|
|
# Set HTML required attribute on required fields
|
|
'set_required': True,
|
|
|
|
# Set HTML disabled attribute on disabled fields
|
|
'set_disabled': False,
|
|
|
|
# Set placeholder attributes to label if no placeholder is provided
|
|
'set_placeholder': True,
|
|
|
|
# Class to indicate required (better to set this in your Django form)
|
|
'required_css_class': '',
|
|
|
|
# Class to indicate error (better to set this in your Django form)
|
|
'error_css_class': 'has-error',
|
|
|
|
# Class to indicate success, meaning the field has valid input
|
|
# (better to set this in your Django form)
|
|
'success_css_class': 'has-success',
|
|
|
|
# Renderers (only set these if you have studied the source and understand
|
|
# the inner workings)
|
|
'formset_renderers': {
|
|
'default': 'bootstrap3.renderers.FormsetRenderer',
|
|
},
|
|
'form_renderers': {
|
|
'default': 'bootstrap3.renderers.FormRenderer',
|
|
},
|
|
'field_renderers': {
|
|
'default': 'bootstrap3.renderers.FieldRenderer',
|
|
'inline': 'bootstrap3.renderers.InlineFieldRenderer',
|
|
},
|
|
}
|
|
|
|
# djangocms_blog config
|
|
|
|
BLOG_ENABLE_COMMENTS = False
|
|
BLOG_USE_PLACEHOLDER = True
|
|
BLOG_IMAGE_THUMBNAIL_SIZE = {'size': '120x120', 'crop': True, 'upscale': False}
|
|
BLOG_IMAGE_FULL_SIZE = {'size': '640x120', 'crop': True, 'upscale': False}
|
|
BLOG_PAGINATION = 4
|
|
BLOG_LATEST_POSTS = BLOG_PAGINATION
|
|
BLOG_POSTS_LIST_TRUNCWORDS_COUNT = 100
|
|
BLOG_MULTISITE = True
|
|
BLOG_AUTHOR_DEFAULT = True
|
|
|
|
# django-meta
|
|
META_SITE_PROTOCOL = "https"
|
|
META_SITE_DOMAIN = "ungleich.ch"
|
|
META_SITE_TYPE = "website"
|
|
META_SITE_NAME = "ungleich"
|
|
META_INCLUDE_KEYWORDS = ["ungleich", "hosting", "switzerland",
|
|
"Schweiz", "Swiss", "cdist"]
|
|
META_USE_SITES = True
|
|
|
|
PARLER_LANGUAGES = {SITE_ID: ({'code': 'en-us'}, {'code': 'de'},)}
|
|
AUTH_USER_MODEL = 'membership.CustomUser'
|
|
|
|
# PAYMENT
|
|
|
|
STRIPE_DESCRIPTION_ON_PAYMENT = "Payment for ungleich GmbH services"
|
|
|
|
# EMAIL MESSAGES
|
|
REGISTRATION_MESSAGE = {
|
|
'subject': "Digital Glarus registration",
|
|
'message': 'Thank You for registering for account on Digital Glarus.'
|
|
}
|
|
STRIPE_API_PRIVATE_KEY = env('STRIPE_API_PRIVATE_KEY')
|
|
STRIPE_API_PUBLIC_KEY = env('STRIPE_API_PUBLIC_KEY')
|
|
STRIPE_API_PRIVATE_KEY_TEST = env('STRIPE_API_PRIVATE_KEY_TEST')
|
|
|
|
ANONYMOUS_USER_NAME = 'anonymous@ungleich.ch'
|
|
GUARDIAN_GET_INIT_ANONYMOUS_USER = 'membership.models.get_anonymous_user_instance'
|
|
|
|
UNGLEICH_SITE_CONFIGS = env('UNGLEICH_SITE_CONFIGS')
|
|
|
|
MULTISITE_CMS_URLS = {}
|
|
if UNGLEICH_SITE_CONFIGS == "":
|
|
raise Exception("Please define UNGLEICH_SITE_CONFIGS in your .env")
|
|
else:
|
|
try:
|
|
configs_dict = json.loads(UNGLEICH_SITE_CONFIGS)
|
|
except ValueError as verr:
|
|
raise Exception("UNGLEICH_SITE_CONFIGS is not a valid JSON: {}".format(
|
|
str(verr)
|
|
))
|
|
else:
|
|
MULTISITE_CMS_URLS = {
|
|
k: v['MULTISITE_CMS_URL'] for (k, v) in configs_dict.items()
|
|
}
|
|
|
|
MULTISITE_CMS_ALIASES = {
|
|
}
|
|
MULTISITE_CMS_FALLBACK = env('MULTISITE_CMS_FALLBACK', 'datacenterlight.ch')
|
|
MULTISITE_FALLBACK = 'django.views.generic.base.RedirectView'
|
|
MULTISITE_FALLBACK_KWARGS = {
|
|
'url': 'https://{}/'.format(MULTISITE_CMS_FALLBACK), 'permanent': False
|
|
}
|
|
|
|
FILER_ENABLE_PERMISSIONS = True
|
|
|
|
#############################################
|
|
# configurations for opennebula-integration #
|
|
#############################################
|
|
|
|
# The oneadmin user name of the OpenNebula infrastructure
|
|
OPENNEBULA_USERNAME = env('OPENNEBULA_USERNAME')
|
|
|
|
# The oneadmin password of the OpenNebula infrastructure
|
|
# The default credentials of the Sandbox OpenNebula VM is
|
|
# oneadmin:opennebula
|
|
OPENNEBULA_PASSWORD = env('OPENNEBULA_PASSWORD')
|
|
|
|
# The protocol is generally http or https
|
|
OPENNEBULA_PROTOCOL = env('OPENNEBULA_PROTOCOL')
|
|
|
|
# The ip address or the domain name of the opennebula infrastructure
|
|
OPENNEBULA_DOMAIN = env('OPENNEBULA_DOMAIN')
|
|
|
|
# The port to connect in order to send an xmlrpc request. The default
|
|
# port is 2633
|
|
OPENNEBULA_PORT = env('OPENNEBULA_PORT')
|
|
|
|
# The endpoint to which the XML RPC request needs to be sent to. The
|
|
# default value is /RPC2
|
|
OPENNEBULA_ENDPOINT = env('OPENNEBULA_ENDPOINT')
|
|
|
|
# The public ssh key of the oneadmin user
|
|
ONEADMIN_USER_SSH_PUBLIC_KEY = env('ONEADMIN_USER_SSH_PUBLIC_KEY')
|
|
|
|
# dcl email configurations
|
|
DCL_TEXT = env('DCL_TEXT')
|
|
DCL_SUPPORT_FROM_ADDRESS = env('DCL_SUPPORT_FROM_ADDRESS')
|
|
|
|
DCL_SSH_KEY_NAME_PREFIX = 'dcl-gen-key-'
|
|
|
|
# Settings for Google analytics
|
|
GOOGLE_ANALYTICS_PROPERTY_IDS = {
|
|
'ungleich.ch': 'UA-62285904-1',
|
|
'digitalglarus.ch': 'UA-62285904-2',
|
|
'blog.ungleich.ch': 'UA-62285904-4',
|
|
'rails-hosting.ch': 'UA-62285904-5',
|
|
'django-hosting.ch': 'UA-62285904-6',
|
|
'node-hosting.ch': 'UA-62285904-7',
|
|
'datacenterlight.ch': 'UA-62285904-8',
|
|
'devuanhosting.ch': 'UA-62285904-9',
|
|
'devuanhosting.com': 'UA-62285904-9',
|
|
'ipv6onlyhosting.com': 'UA-62285904-10',
|
|
'comic.ungleich.ch': 'UA-62285904-13',
|
|
'127.0.0.1:8000': 'localhost',
|
|
'dynamicweb-development.ungleich.ch': 'development',
|
|
'dynamicweb-staging.ungleich.ch': 'staging'
|
|
}
|
|
|
|
# CELERY Settings
|
|
CELERY_BROKER_URL = env('CELERY_BROKER_URL')
|
|
CELERY_RESULT_BACKEND = env('CELERY_RESULT_BACKEND')
|
|
CELERY_ACCEPT_CONTENT = ['application/json']
|
|
CELERY_TASK_SERIALIZER = 'json'
|
|
CELERY_RESULT_SERIALIZER = 'json'
|
|
# CELERY_TIMEZONE = 'Europe/Zurich'
|
|
CELERY_MAX_RETRIES = int_env('CELERY_MAX_RETRIES', 5)
|
|
|
|
DCL_ERROR_EMAILS_TO = env('DCL_ERROR_EMAILS_TO')
|
|
ADMIN_EMAIL = env('ADMIN_EMAIL')
|
|
|
|
DCL_ERROR_EMAILS_TO_LIST = []
|
|
if DCL_ERROR_EMAILS_TO is not None:
|
|
DCL_ERROR_EMAILS_TO_LIST = [
|
|
x.strip() for x in DCL_ERROR_EMAILS_TO.split(',')
|
|
] if "," in DCL_ERROR_EMAILS_TO else [DCL_ERROR_EMAILS_TO.strip()]
|
|
|
|
if 'info@ungleich.ch' not in DCL_ERROR_EMAILS_TO_LIST:
|
|
DCL_ERROR_EMAILS_TO_LIST.append('info@ungleich.ch')
|
|
|
|
ENABLE_LOGGING = bool_env('ENABLE_LOGGING')
|
|
MODULES_TO_LOG = env('MODULES_TO_LOG')
|
|
LOG_LEVEL = env('LOG_LEVEL')
|
|
|
|
if LOG_LEVEL is None:
|
|
LOG_LEVEL = 'DEBUG'
|
|
|
|
if ENABLE_LOGGING:
|
|
loggers_dict = {}
|
|
handlers_dict = {}
|
|
if MODULES_TO_LOG is None:
|
|
# set MODULES_TO_LOG to django, if it is not set
|
|
MODULES_TO_LOG = 'django'
|
|
modules_to_log_list = MODULES_TO_LOG.split(',')
|
|
for custom_module in modules_to_log_list:
|
|
logger_item = {
|
|
custom_module: {
|
|
'handlers': ['custom_file'],
|
|
'level': LOG_LEVEL,
|
|
'propagate': True
|
|
}
|
|
}
|
|
loggers_dict.update(logger_item)
|
|
|
|
custom_handler_item = {
|
|
'custom_file': {
|
|
'level': LOG_LEVEL,
|
|
'class': 'logging.handlers.RotatingFileHandler',
|
|
'filename':
|
|
"{PROJECT_DIR}/logs/{LEVEL}.log".format(
|
|
LEVEL=LOG_LEVEL.lower(),
|
|
PROJECT_DIR=PROJECT_DIR
|
|
),
|
|
'maxBytes': 1024 * 1024 * 5,
|
|
'backupCount': 10,
|
|
'formatter': 'standard',
|
|
}
|
|
}
|
|
handlers_dict.update(custom_handler_item)
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': False,
|
|
'formatters': {
|
|
'standard': {
|
|
'format': '%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
|
|
}
|
|
},
|
|
'handlers': handlers_dict,
|
|
'loggers': loggers_dict
|
|
}
|
|
|
|
TEST_MANAGE_SSH_KEY_PUBKEY = env('TEST_MANAGE_SSH_KEY_PUBKEY')
|
|
TEST_MANAGE_SSH_KEY_HOST = env('TEST_MANAGE_SSH_KEY_HOST')
|
|
|
|
X_FRAME_OPTIONS_ALLOW_FROM_URI = env('X_FRAME_OPTIONS_ALLOW_FROM_URI')
|
|
X_FRAME_OPTIONS = ('SAMEORIGIN' if X_FRAME_OPTIONS_ALLOW_FROM_URI is None else
|
|
'ALLOW-FROM {}'.format(
|
|
X_FRAME_OPTIONS_ALLOW_FROM_URI.strip()
|
|
))
|
|
|
|
WEBHOOK_SECRET = env('WEBHOOK_SECRET')
|
|
|
|
DEBUG = bool_env('DEBUG')
|
|
ADD_TRIAL_PERIOD_TO_SUBSCRIPTION = bool_env('ADD_TRIAL_PERIOD_TO_SUBSCRIPTION')
|
|
|
|
|
|
# LDAP setup
|
|
LDAP_ADMIN_DN = env('LDAP_ADMIN_DN')
|
|
LDAP_ADMIN_PASSWORD = env('LDAP_ADMIN_PASSWORD')
|
|
AUTH_LDAP_SERVER = env('LDAPSERVER')
|
|
|
|
LDAP_CUSTOMER_DN = env('LDAP_CUSTOMER_DN')
|
|
LDAP_CUSTOMER_GROUP_ID = int(env('LDAP_CUSTOMER_GROUP_ID'))
|
|
LDAP_MAX_UID_FILE_PATH = os.environ.get('LDAP_MAX_UID_FILE_PATH',
|
|
os.path.join(os.path.abspath(os.path.dirname(__file__)), 'ldap_max_uid_file')
|
|
)
|
|
LDAP_DEFAULT_START_UID = int(env('LDAP_DEFAULT_START_UID'))
|
|
|
|
# Search union over OUs
|
|
AUTH_LDAP_START_TLS = bool(os.environ.get('LDAP_USE_TLS', False))
|
|
|
|
ENTIRE_SEARCH_BASE = env("ENTIRE_SEARCH_BASE")
|
|
|
|
|
|
AUTH_LDAP_USER_ATTR_MAP = {
|
|
"first_name": "givenName",
|
|
"last_name": "sn",
|
|
"email": "mail"
|
|
}
|
|
|
|
READ_VM_REALM = env('READ_VM_REALM')
|
|
AUTH_NAME = env('AUTH_NAME')
|
|
AUTH_SEED = env('AUTH_SEED')
|
|
AUTH_REALM = env('AUTH_REALM')
|
|
OTP_SERVER = env('OTP_SERVER')
|
|
OTP_VERIFY_ENDPOINT = env('OTP_VERIFY_ENDPOINT')
|
|
|
|
FIRST_VM_ID_AFTER_EU_VAT = int_env('FIRST_VM_ID_AFTER_EU_VAT')
|
|
PRE_EU_VAT_RATE = float(env('PRE_EU_VAT_RATE'))
|
|
|
|
VM_BASE_PRICE = float(env('VM_BASE_PRICE'))
|
|
|
|
UPDATED_TEMPLATES_STR = env('UPDATED_TEMPLATES')
|
|
UPDATED_TEMPLATES_DICT = {}
|
|
if UPDATED_TEMPLATES_STR:
|
|
UPDATED_TEMPLATES_DICT = eval(UPDATED_TEMPLATES_STR)
|
|
|
|
MAX_TIME_TO_WAIT_FOR_VM_TERMINATE = int_env(
|
|
'MAX_TIME_TO_WAIT_FOR_VM_TERMINATE', 15)
|
|
|
|
if DEBUG:
|
|
from .local import * # flake8: noqa
|
|
else:
|
|
from .prod import * # flake8: noqa
|
|
|
|
# Try to load dynamic configuration, if it exists
|
|
try:
|
|
from .dynamic import * # flake8: noqa
|
|
except ImportError:
|
|
pass
|