class Base(Core): """Settings that may change per-environment, some with defaults.""" # Flags that affect other settings, via setting methods below LOGGING_USE_JSON = values.BooleanValue(False) USE_OIDC = values.BooleanValue(False) # General settings DEBUG = values.BooleanValue(False) ADMINS = values.SingleNestedListValue([]) SILENCED_SYSTEM_CHECKS = values.ListValue([ # Check CSRF cookie http only. disabled because we read the # CSRF cookie in JS for forms in React. 'security.W017', ]) # Authentication def AUTHENTICATION_BACKENDS(self): if self.USE_OIDC: return ['normandy.base.auth_backends.LoggingRemoteUserBackend'] else: return ['normandy.base.auth_backends.LoggingModelBackend'] OIDC_REMOTE_AUTH_HEADER = values.Value('HTTP_REMOTE_USER') OIDC_LOGOUT_URL = values.Value(None) # Middleware that _most_ environments will need. Subclasses can override this list. EXTRA_MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ] def MIDDLEWARE(self): """ Determine middleware by combining the core set and per-environment set. """ middleware = Core.MIDDLEWARE + self.EXTRA_MIDDLEWARE if self.USE_OIDC: middleware.append('normandy.base.middleware.ConfigurableRemoteUserMiddleware') return middleware def LOGGING(self): return { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'json': { '()': 'mozilla_cloud_services_logger.formatters.JsonLogFormatter', 'logger_name': 'normandy', }, 'development': { 'format': '%(levelname)s %(asctime)s %(name)s %(message)s', }, }, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'json' if self.LOGGING_USE_JSON else 'development', }, }, 'root': { 'handlers': ['console'], 'level': 'WARNING', }, 'loggers': { 'normandy': { 'propagate': False, 'handlers': ['console'], 'level': 'DEBUG', }, 'request.summary': { 'propagate': False, 'handlers': ['console'], 'level': 'DEBUG', }, }, } # Remote services DATABASES = values.DatabaseURLValue('postgres://postgres@localhost/normandy') CONN_MAX_AGE = values.IntegerValue(0) GEOIP2_DATABASE = values.Value(os.path.join(Core.BASE_DIR, 'GeoLite2-Country.mmdb')) # Email settings EMAIL_HOST_USER = values.Value() EMAIL_HOST = values.Value() EMAIL_PORT = values.IntegerValue(587) EMAIL_USE_TLS = values.BooleanValue(True) EMAIL_HOST_PASSWORD = values.Value() EMAIL_BACKEND = values.Value('django.core.mail.backends.smtp.EmailBackend') def RAVEN_CONFIG(self): version_path = os.path.join(Core.BASE_DIR, '__version__', 'tag') try: with open(version_path) as f: version = f.read().strip() except IOError: version = None return { 'dsn': values.URLValue(None, environ_name='RAVEN_CONFIG_DSN'), 'release': values.Value(version, environ_name='RAVEN_CONFIG_RELEASE'), } # statsd STATSD_HOST = values.Value('localhost') STATSD_PORT = values.IntegerValue(8125) STATSD_IPV6 = values.BooleanValue(False) STATSD_PREFIX = values.Value('normandy') STATSD_MAXUDPSIZE = values.IntegerValue(512) # Security settings SECRET_KEY = values.SecretValue() ALLOWED_HOSTS = values.ListValue([]) AUTH_PASSWORD_VALIDATORS = [ {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, ] PASSWORD_HASHERS = values.ListValue([ 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 'django.contrib.auth.hashers.PBKDF2PasswordHasher', ]) USE_X_FORWARDED_HOST = values.BooleanValue(False) SECURE_PROXY_SSL_HEADER = values.TupleValue() SECURE_HSTS_SECONDS = values.IntegerValue(3600) SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue(True) CSRF_COOKIE_HTTPONLY = values.BooleanValue(False) CSRF_COOKIE_SECURE = values.BooleanValue(True) SECURE_SSL_REDIRECT = values.BooleanValue(True) SECURE_REDIRECT_EXEMPT = values.ListValue([]) SESSION_COOKIE_SECURE = values.BooleanValue(True) SECURE_BROWSER_XSS_FILTER = values.BooleanValue(True) SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue(True) X_FRAME_OPTIONS = values.Value('DENY') REQUIRE_RECIPE_AUTH = values.BooleanValue(True) # Media and static settings STATIC_URL = values.Value('/static/') STATIC_ROOT = values.Value(os.path.join(Core.BASE_DIR, 'static')) MEDIA_URL = values.Value('/media/') MEDIA_ROOT = values.Value(os.path.join(Core.BASE_DIR, 'media')) STATICFILES_DIRS = ( os.path.join(Core.BASE_DIR, 'assets'), ) # URL that the CDN exists at to front cached parts of the site, if any. CDN_URL = values.URLValue(None) # URL that bypasses any CDNs APP_SERVER_URL = values.URLValue(None) # URL for the CSP report-uri directive. CSP_REPORT_URI = values.Value('/__cspreport__') # Normandy settings ADMIN_ENABLED = values.BooleanValue(True) ACTION_IMPLEMENTATION_CACHE_TIME = values.IntegerValue(60 * 60 * 24 * 365) NUM_PROXIES = values.IntegerValue(0) API_CACHE_TIME = values.IntegerValue(30) API_CACHE_ENABLED = values.BooleanValue(True) # If true, approvals must come from two separate users. If false, the same # user can approve their own request. PEER_APPROVAL_ENFORCED = values.BooleanValue(True) # Autograph settings AUTOGRAPH_URL = values.Value() AUTOGRAPH_HAWK_ID = values.Value() AUTOGRAPH_HAWK_SECRET_KEY = values.Value() AUTOGRAPH_SIGNATURE_MAX_AGE = values.IntegerValue(60 * 60 * 24 * 7) AUTOGRAPH_X5U_CACHE_BUST = values.Value(None) # How many days before expiration to warn for expired certificates CERTIFICATES_EXPIRE_EARLY_DAYS = values.IntegerValue(None) PROD_DETAILS_DIR = values.Value(os.path.join(Core.BASE_DIR, 'product_details')) # AWS settings AWS_ACCESS_KEY_ID = values.Value() AWS_SECRET_ACCESS_KEY = values.Value() AWS_STORAGE_BUCKET_NAME = values.Value() GITHUB_URL = values.Value('https://github.com/mozilla/normandy')
class Base(Core, CORS, OIDC, Metrics): """Settings that may change per-environment, some with defaults.""" # Flags that affect other settings, via setting methods below LOGGING_USE_JSON = values.BooleanValue(False) USE_OIDC = values.BooleanValue(False) # General settings DEBUG = values.BooleanValue(False) ADMINS = values.SingleNestedListValue([]) SILENCED_SYSTEM_CHECKS = values.ListValue([ # We've subclassed Django's security middleware, so Django's # checks can't tell we are using the middleware. "security.W001", # We have disabled CSRF as we do not use cookie-based authentication. # As a result the CSRF middleware check is not required. "security.W003", ]) # Authentication def AUTHENTICATION_BACKENDS(self): if self.USE_OIDC: return ["normandy.base.auth_backends.EmailOnlyRemoteUserBackend"] else: return ["normandy.base.auth_backends.LoggingModelBackend"] OIDC_REMOTE_AUTH_HEADER = values.Value("HTTP_REMOTE_USER") # Middleware that _most_ environments will need. Subclasses can override this list. EXTRA_MIDDLEWARE = [ "django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", ] def MIDDLEWARE(self): """ Determine middleware by combining the core set and per-environment set. """ middleware = Core.MIDDLEWARE + self.EXTRA_MIDDLEWARE if self.USE_OIDC: middleware.append( "normandy.base.middleware.ConfigurableRemoteUserMiddleware") return middleware def LOGGING(self): return { "version": 1, "disable_existing_loggers": False, "formatters": { "json": { "()": "dockerflow.logging.JsonLogFormatter", "logger_name": "normandy" }, "development": { "format": "%(levelname)s %(asctime)s %(name)s %(message)s" }, }, "handlers": { "console": { "level": "DEBUG", "class": "logging.StreamHandler", "formatter": "json" if self.LOGGING_USE_JSON else "development", } }, "root": { "handlers": ["console"], "level": "WARNING" }, "loggers": { "normandy": { "propagate": False, "handlers": ["console"], "level": "DEBUG" }, "request.summary": { "propagate": False, "handlers": ["console"], "level": "DEBUG" }, }, } # Remote services DATABASES = values.DatabaseURLValue( "postgres://postgres@localhost/normandy") CONN_MAX_AGE = values.IntegerValue(0) GEOIP2_DATABASE = values.Value( os.path.join(Core.BASE_DIR, "GeoLite2-Country.mmdb")) # Email settings EMAIL_HOST_USER = values.Value() EMAIL_HOST = values.Value() EMAIL_PORT = values.IntegerValue(587) EMAIL_USE_TLS = values.BooleanValue(True) EMAIL_HOST_PASSWORD = values.Value() EMAIL_BACKEND = values.Value("django.core.mail.backends.smtp.EmailBackend") def RAVEN_CONFIG(self): version_path = os.path.join(Core.BASE_DIR, "version.json") try: with open(version_path) as f: build_info = json.loads(f.read()) version = build_info.get("version") except IOError: version = None return { "dsn": values.URLValue(None, environ_name="RAVEN_CONFIG_DSN"), "release": values.Value(version, environ_name="RAVEN_CONFIG_RELEASE"), } # statsd STATSD_HOST = values.Value("localhost") STATSD_PORT = values.IntegerValue(8125) STATSD_IPV6 = values.BooleanValue(False) STATSD_PREFIX = values.Value("normandy") STATSD_MAXUDPSIZE = values.IntegerValue(512) # Security settings SECRET_KEY = values.SecretValue() ALLOWED_HOSTS = values.ListValue([]) AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator" }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator" }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator" }, ] PASSWORD_HASHERS = values.ListValue([ "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", ]) USE_X_FORWARDED_HOST = values.BooleanValue(False) SECURE_PROXY_SSL_HEADER = values.TupleValue() SECURE_HSTS_SECONDS = values.IntegerValue(3600) SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue(True) CSRF_COOKIE_HTTPONLY = values.BooleanValue(True) CSRF_COOKIE_SECURE = values.BooleanValue(True) SECURE_SSL_REDIRECT = values.BooleanValue(True) SECURE_REDIRECT_EXEMPT = values.ListValue([]) SESSION_COOKIE_SECURE = values.BooleanValue(True) SECURE_BROWSER_XSS_FILTER = values.BooleanValue(True) SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue(True) X_FRAME_OPTIONS = values.Value("DENY") REQUIRE_RECIPE_AUTH = values.BooleanValue(True) # Media and static settings STATIC_URL = values.Value("/static/") STATIC_ROOT = values.Value(os.path.join(Core.BASE_DIR, "static")) MEDIA_URL = values.Value("/media/") MEDIA_ROOT = values.Value(os.path.join(Core.BASE_DIR, "media")) STATICFILES_DIRS = (os.path.join(Core.BASE_DIR, "assets"), ) # URL that the CDN exists at to front cached parts of the site, if any. CDN_URL = values.URLValue(None) # URL that bypasses any CDNs APP_SERVER_URL = values.URLValue(None) # URL for the CSP report-uri directive. CSP_REPORT_URI = values.Value("/__cspreport__") # Normandy settings ADMIN_ENABLED = values.BooleanValue(True) IMMUTABLE_CACHE_TIME = values.IntegerValue(60 * 60 * 24 * 365) NUM_PROXIES = values.IntegerValue(0) API_CACHE_TIME = values.IntegerValue(30) API_CACHE_ENABLED = values.BooleanValue(True) PERMANENT_REDIRECT_CACHE_TIME = values.IntegerValue(60 * 60 * 24 * 30) HTTPS_REDIRECT_CACHE_TIME = values.IntegerValue(60 * 60 * 24 * 30) # If true, approvals must come from two separate users. If false, the same # user can approve their own request. PEER_APPROVAL_ENFORCED = values.BooleanValue(True) # Autograph settings AUTOGRAPH_URL = values.Value() AUTOGRAPH_HAWK_ID = values.Value() AUTOGRAPH_HAWK_SECRET_KEY = values.Value() AUTOGRAPH_SIGNATURE_MAX_AGE = values.IntegerValue(60 * 60 * 24 * 7) AUTOGRAPH_X5U_CACHE_BUST = values.Value(None) # Remote Settings connection configuration REMOTE_SETTINGS_URL = values.Value() REMOTE_SETTINGS_USERNAME = values.Value() REMOTE_SETTINGS_PASSWORD = values.Value() REMOTE_SETTINGS_BUCKET_ID = values.Value("main-workspace") REMOTE_SETTINGS_COLLECTION_ID = values.Value("normandy-recipes") REMOTE_SETTINGS_RETRY_REQUESTS = values.IntegerValue(3) # How many days before expiration to warn for expired certificates CERTIFICATES_EXPIRE_EARLY_DAYS = values.IntegerValue(None) CERTIFICATES_CHECK_VALIDITY = values.BooleanValue(True) CERTIFICATES_EXPECTED_ROOT_HASH = values.Value(None) CERTIFICATES_EXPECTED_SUBJECT_CN = values.Value( "normandy.content-signature.mozilla.org") # Storage settings DEFAULT_FILE_STORAGE = values.Value( "normandy.base.storage.NormandyS3Boto3Storage") PROD_DETAILS_DIR = values.Value( os.path.join(Core.BASE_DIR, "product_details")) # AWS settings AWS_ACCESS_KEY_ID = values.Value() AWS_SECRET_ACCESS_KEY = values.Value() AWS_STORAGE_BUCKET_NAME = values.Value() GS_BUCKET_NAME = values.Value() GS_DEFAULT_ACL = values.Value("publicRead") GITHUB_URL = values.Value("https://github.com/mozilla/normandy")
class Settings(Configuration): ACCESS_TOKEN_LIFETIME_MINUTES = values.FloatValue() ADMIN_HEADER_COLOR = values.Value() ADMIN_HEADER_TITLE = "{environment}{title}".format( environment=ENVIRONMENT or '{DJANGO_ENVIRONMENT}', title=values.Value('{DJANGO_ADMIN_HEADER_TITLE}', environ_name='ADMIN_HEADER_TITLE'), ) ADMINS = values.SingleNestedListValue([]) ALLOWED_HOSTS = values.ListValue([]) ANYMAIL = values.DictValue() AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] AUTH_USER_MODEL = "main.User" CORS_ORIGIN_WHITELIST = values.ListValue([]) DATABASE_ENGINE = values.Value(environ_required=True) DATABASE_NAME = values.Value(environ_required=True) DATABASE_USER = values.Value() DATABASE_PASSWORD = values.Value() DATABASE_HOST = values.Value() DATABASE_PORT = values.Value() @property def DATABASES(self): return { 'default': { 'ENGINE': self.DATABASE_ENGINE, 'NAME': self.DATABASE_NAME, 'USER': self.DATABASE_USER, 'PASSWORD': self.DATABASE_PASSWORD, 'HOST': self.DATABASE_HOST, 'PORT': self.DATABASE_PORT, } } # SECURITY WARNING: don't run with debug turned on in production! DEBUG = values.BooleanValue(False) DEFAULT_FROM_EMAIL = values.Value() ELASTICSEARCH_HOST = values.Value() ELASTICSEARCH_PORT = values.Value() @property def ELASTICSEARCH_DSL(self): # https://django-configurations.readthedocs.io/en/stable/patterns/#property-settings return { 'default': { 'hosts': 'http://{}:{}'.format(self.ELASTICSEARCH_HOST, self.ELASTICSEARCH_PORT) } } EMAIL_BACKEND = values.Value() EMAIL_HOST = values.Value() EMAIL_HOST_PASSWORD = values.Value() EMAIL_HOST_USER = values.Value() EMAIL_PORT = values.Value() EMAIL_USE_TLS = values.BooleanValue(False) INSTALLED_APPS = [ # Django apps 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Third party 'anymail', 'django_extensions', 'django_elasticsearch_dsl', 'rest_framework', 'rest_framework_simplejwt.token_blacklist', 'corsheaders', 'django_filters', # Local apps 'main.apps.MainConfig' ] LANGUAGE_CODE = values.Value('en-us') LOGGING = logging_config() MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'main.middleware.timezone_middleware.TimezoneMiddleware', ] RECAPTCHA_PRIVATE_KEY = values.SecretValue() RECAPTCHA_URL = values.Value( default="https://www.google.com/recaptcha/api/siteverify") REST_FRAMEWORK = { 'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S', 'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication', ), 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_RENDERER_CLASSES': ('rest_framework.renderers.JSONRenderer', ), 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning', } ROOT_URLCONF = 'storageofknowledge.urls' SECRET_KEY = values.SecretValue() SERVER_EMAIL = values.Value() SESSION_COOKIE_AGE = values.IntegerValue(5 * 60) # 5 minutes SESSION_SAVE_EVERY_REQUEST = values.BooleanValue(True) @property def SIMPLE_JWT(self): # https://django-configurations.readthedocs.io/en/stable/patterns/#property-settings return { 'ROTATE_REFRESH_TOKENS': True, 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=self.ACCESS_TOKEN_LIFETIME_MINUTES) } STATIC_ROOT = values.Value(None) STATIC_URL = '/static/' STATICFILES_DIRS = values.SingleNestedListValue([]) STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [(os.path.join(BASE_DIR, "templates"))], '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', 'main.context_processors.from_settings', ], }, }, ] TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True USER_CONFIRMATION_LIFETIME_HOURS = values.FloatValue() WSGI_APPLICATION = 'storageofknowledge.wsgi.application'
class Base(Configuration, Celery): # Web Settings SECRET_KEY = values.SecretValue() # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'ugrryo)w9y0(*i^-zjq+%)=o^g*-0l%l*7!5qzrg3j$y3mtp*$' # Password validation # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators @property def CACHES(self): return { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': self.REDIS_URL, 'OPTIONS': { 'COMPRESSOR': 'django_redis.compressors.zlib.ZlibCompressor', # noqa 'SERIALIZER': 'django_redis.serializers.json.JSONSerializer', # noqa }, }, } AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = values.Value('UTC', environ_prefix=None) USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' CONN_MAX_AGE = values.IntegerValue(60, environ_prefix=None) ALLOWED_HOSTS = values.ListValue([], environ_prefix=None) CORS_ORIGIN = values.Value(environ_prefix=None) USE_X_FORWARDED_HOST = values.BooleanValue(False, environ_prefix=None) # Application definition INSTALLED_APPS = [ 'relops_hardware_controller.apps.RelopsHardwareControllerAppConfig', 'relops_hardware_controller.api', 'django_celery_results', 'rest_framework', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'relops_hardware_controller.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], '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', ], }, }, ] WSGI_APPLICATION = 'relops_hardware_controller.wsgi.application' SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_CACHE_ALIAS = 'default' REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': (), 'DEFAULT_RENDERER_CLASSES': ('rest_framework.renderers.JSONRenderer', ), 'UNAUTHENTICATED_USER': '******', } TASKCLUSTER_CLIENT_ID = values.Value(environ_prefix=None) TASKCLUSTER_ACCESS_TOKEN = values.SecretValue(environ_prefix=None) TASK_NAMES = values.ListValue([ 'ping', 'status', 'reboot', 'ipmi_off', 'ipmi_on', 'ipmi_list', 'ipmi_cycle', 'ipmi_reset', 'reimage', 'loan', 'return_loan', ], environ_prefix=None) REQUIRED_TASKCLUSTER_SCOPE_SETS = values.SingleNestedListValue( [['project:releng:roller:{}'.format(task_name)] for task_name in TASK_NAMES.value], seq_separator=',', environ_prefix=None) VALID_WORKER_ID_REGEX = values.Value('^.*', environ_prefix=None) # Worker Settings NOTIFY_EMAIL = values.Value('*****@*****.**', environ_prefix=None) NOTIFY_IRC_CHANNEL = values.Value('#roller', environ_prefix=None) BUGZILLA_URL = values.URLValue('https://bugzilla.mozilla.org', environ_prefix=None) BUGZILLA_API_KEY = values.SecretValue(environ_prefix=None) BUGZILLA_REOPEN_STATE = values.Value('REOPENED', environ_prefix=None) BUGZILLA_REBOOT_TEMPLATE = values.Value(json.dumps( dict( api_key='${api_key}', product='Infrastructure & Operations', component='DCOps', cc='${cc}', summary='${hostname} is unreachable', version='unspecified', description= 'Reboot ${hostname} ${ip}\nRequested by ${client_id}\nRelops controller action failed:${log}', blocks='${blocks}', )), environ_prefix=None) BUGZILLA_WORKER_TRACKER_TEMPLATE = values.Value(json.dumps( dict( api_key='${api_key}', product='Infrastructure & Operations', component='CIDuty', summary='[${DC}] ${alias} problem tracking', version='unspecified', alias='${alias}', )), environ_prefix=None) XEN_URL = values.URLValue('', environ_prefix=None) XEN_USERNAME = values.Value('', environ_prefix=None) XEN_PASSWORD = values.Value('', environ_prefix=None) ILO_USERNAME = values.Value('', environ_prefix=None) ILO_PASSWORD = values.Value('', environ_prefix=None) WORKER_CONFIG = JSONFileValue('', environ_prefix=None, environ_name='WORKER_CONFIG_PATH') # how many seconds to wait for a machine to go down and come back up DOWN_TIMEOUT = values.IntegerValue(60, environ_prefix=None) UP_TIMEOUT = values.IntegerValue(300, environ_prefix=None) REBOOT_METHODS = values.ListValue( [ 'ssh_reboot', 'ipmi_reset', 'ipmi_cycle', 'snmp_reboot', # snmp pdu for mac minis 'file_bugzilla_bug', # give up and file a bug ], environ_prefix=None)
class Base(Core): """Settings that may change per-environment, some with defaults.""" # General settings DEBUG = values.BooleanValue(False) ADMINS = values.SingleNestedListValue([]) # Remote services DATABASES = values.DatabaseURLValue( 'postgres://postgres@localhost/normandy') GEOIP2_DATABASE = values.Value( os.path.join(Core.BASE_DIR, 'GeoLite2-Country.mmdb')) # Email settings EMAIL_HOST_USER = values.Value() EMAIL_HOST = values.Value() EMAIL_PORT = values.IntegerValue(587) EMAIL_USE_TLS = values.BooleanValue(True) EMAIL_HOST_PASSWORD = values.Value() EMAIL_BACKEND = values.Value('django.core.mail.backends.smtp.EmailBackend') RAVEN_CONFIG = { 'dsn': values.URLValue(None, environ_name='RAVEN_CONFIG_DSN'), } PROD_DETAILS_STORAGE = values.Value( 'normandy.recipes.storage.ProductDetailsRelationalStorage') # statsd STATSD_HOST = values.Value('localhost') STATSD_PORT = values.IntegerValue(8125) STATSD_IPV6 = values.BooleanValue(False) STATSD_PREFIX = values.Value('normandy') STATSD_MAXUDPSIZE = values.IntegerValue(512) # Security settings SECRET_KEY = values.SecretValue() ALLOWED_HOSTS = values.ListValue([]) AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator' }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator' }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator' }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator' }, ] PASSWORD_HASHERS = values.ListValue([ 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 'django.contrib.auth.hashers.PBKDF2PasswordHasher', ]) USE_X_FORWARDED_HOST = values.BooleanValue(False) SECURE_PROXY_SSL_HEADER = values.TupleValue() SECURE_HSTS_SECONDS = values.IntegerValue(3600) SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue(True) CSRF_COOKIE_HTTPONLY = values.BooleanValue(True) CSRF_COOKIE_SECURE = values.BooleanValue(True) SECURE_SSL_REDIRECT = values.BooleanValue(True) SECURE_REDIRECT_EXEMPT = values.ListValue([]) SESSION_COOKIE_SECURE = values.BooleanValue(True) SECURE_BROWSER_XSS_FILTER = values.BooleanValue(True) SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue(True) X_FRAME_OPTIONS = values.Value('DENY') # Media and static settings STATIC_URL = values.Value('/static/') STATIC_ROOT = values.Value(os.path.join(Core.BASE_DIR, 'static')) MEDIA_URL = values.Value('/media/') MEDIA_ROOT = values.Value(os.path.join(Core.BASE_DIR, 'media')) STATICFILES_STORAGE = values.Value( 'normandy.storage.GzipManifestPipelineStorage') # Overwrite old files when uploading media. DEFAULT_FILE_STORAGE = values.Value( 'storages.backends.overwrite.OverwriteStorage') # URL that the CDN exists at to front cached parts of the site, if any. CDN_URL = values.URLValue(None) # Normandy settings CAN_EDIT_ACTIONS_IN_USE = values.BooleanValue(False) ADMIN_ENABLED = values.BooleanValue(True) ACTION_IMPLEMENTATION_CACHE_TIME = values.IntegerValue(60 * 60 * 24 * 365)