settings.py 10.1 KB
Newer Older
baltery's avatar
baltery 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
"""
Django settings for jumpserver project.

Generated by 'django-admin startproject' using Django 1.10.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""

import os
W
wangyong 已提交
14 15 16
import sys

from django.urls import reverse_lazy
baltery's avatar
baltery 已提交
17 18 19

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
W
wangyong 已提交
20 21 22 23 24 25 26
PROJECT_DIR = os.path.dirname(BASE_DIR)

sys.path.append(PROJECT_DIR)

# Import project config setting
try:
    from config import config as env_config, env
baltery's avatar
baltery 已提交
27

W
wangyong 已提交
28 29 30
    CONFIG = env_config.get(env, 'default')()
except ImportError:
    CONFIG = type('_', (), {'__getattr__': None})()
baltery's avatar
baltery 已提交
31 32 33 34 35

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
baltery's avatar
baltery 已提交
36
SECRET_KEY = CONFIG.SECRET_KEY
baltery's avatar
baltery 已提交
37 38

# SECURITY WARNING: don't run with debug turned on in production!
W
wangyong 已提交
39 40 41 42 43 44
DEBUG = CONFIG.DEBUG or False


# Absolute url for some case, for example email link
SITE_URL = CONFIG.SITE_URL or 'http://localhost'

baltery's avatar
baltery 已提交
45

W
wangyong 已提交
46 47
# LOG LEVEL
LOG_LEVEL = 'DEBUG' if DEBUG else CONFIG.LOG_LEVEL or 'WARNING'
baltery's avatar
baltery 已提交
48

W
wangyong 已提交
49
ALLOWED_HOSTS = CONFIG.ALLOWED_HOSTS or []
baltery's avatar
baltery 已提交
50 51 52 53

# Application definition

INSTALLED_APPS = [
54 55 56 57 58
    'users.apps.UsersConfig',
    'assets.apps.AssetsConfig',
    'perms.apps.PermsConfig',
    'ops.apps.OpsConfig',
    'audits.apps.AuditsConfig',
W
wangyong 已提交
59
    'common.apps.CommonConfig',
60
    'applications.apps.ApplicationsConfig',
W
wangyong 已提交
61
    'rest_framework',
baltery's avatar
baltery 已提交
62
    'bootstrap3',
baltery's avatar
baltery 已提交
63
    'captcha',
baltery's avatar
baltery 已提交
64 65 66 67 68
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
W
wangyong 已提交
69

baltery's avatar
baltery 已提交
70 71 72 73 74
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
baltery's avatar
baltery 已提交
75
    'django.middleware.locale.LocaleMiddleware',
baltery's avatar
baltery 已提交
76 77 78 79 80
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
81
    'jumpserver.middleware.TimezoneMiddleware',
baltery's avatar
baltery 已提交
82
    'jumpserver.middleware.DemoMiddleware',
baltery's avatar
baltery 已提交
83 84 85 86 87 88 89 90 91 92 93
]

ROOT_URLCONF = 'jumpserver.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
baltery's avatar
baltery 已提交
94
                'django.template.context_processors.i18n',
baltery's avatar
baltery 已提交
95 96 97 98
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
W
wangyong 已提交
99 100
                'django.template.context_processors.static',
                'django.template.context_processors.request',
baltery's avatar
baltery 已提交
101
                'django.template.context_processors.media',
baltery's avatar
baltery 已提交
102 103 104 105 106
            ],
        },
    },
]

107
# WSGI_APPLICATION = 'jumpserver.wsgi.applications'
baltery's avatar
baltery 已提交
108

W
wangyong 已提交
109
LOGIN_REDIRECT_URL = reverse_lazy('index')
baltery's avatar
baltery 已提交
110
LOGIN_URL = reverse_lazy('users:login')
baltery's avatar
baltery 已提交
111

112 113 114 115
SESSION_COOKIE_DOMAIN = CONFIG.SESSION_COOKIE_DOMAIN or None
CSRF_COOKIE_DOMAIN = CONFIG.CSRF_COOKIE_DOMAIN or None
SESSION_COOKIE_AGE = CONFIG.SESSION_COOKIE_AGE or 3600*24

baltery's avatar
baltery 已提交
116 117

MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
baltery's avatar
baltery 已提交
118 119 120
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

W
wangyong 已提交
121 122 123 124
if CONFIG.DB_ENGINE == 'sqlite':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
G
GuangHongwei 已提交
125
            'NAME': CONFIG.DB_NAME or os.path.join(BASE_DIR, 'data', 'db.sqlite3'),
baltery's avatar
baltery 已提交
126
            'ATOMIC_REQUESTS': True,
W
wangyong 已提交
127 128 129 130 131 132 133 134 135 136 137
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.%s' % CONFIG.DB_ENGINE,
            'NAME': CONFIG.DB_NAME,
            'HOST': CONFIG.DB_HOST,
            'PORT': CONFIG.DB_PORT,
            'USER': CONFIG.DB_USER,
            'PASSWORD': CONFIG.DB_PASSWORD,
baltery's avatar
baltery 已提交
138
            'ATOMIC_REQUESTS': True,
W
wangyong 已提交
139
        }
baltery's avatar
baltery 已提交
140 141 142 143
    }

# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
W
wangyong 已提交
144
#
baltery's avatar
baltery 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
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',
    },
]

W
wangyong 已提交
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
# Logging setting
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'main': {
            'datefmt': '%Y-%m-%d %H:%M:%S',
            'format': '%(asctime)s [%(module)s %(levelname)s] %(message)s',
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'null': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'main'
        },
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'formatter': 'main',
            'filename': os.path.join(PROJECT_DIR, 'logs', 'jumpserver.log')
        },
A
Administrator 已提交
192 193 194 195 196 197
        'ansible_logs': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'formatter': 'main',
            'filename': os.path.join(PROJECT_DIR, 'logs', 'ansible.log')
        },
W
wangyong 已提交
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
    },
    'loggers': {
        'django': {
            'handlers': ['null'],
            'propagate': False,
            'level': LOG_LEVEL,
        },
        'django.request': {
            'handlers': ['console', 'file'],
            'level': LOG_LEVEL,
            'propagate': False,
        },
        'django.server': {
            'handlers': ['console', 'file'],
            'level': LOG_LEVEL,
            'propagate': False,
        },
        'jumpserver': {
            'handlers': ['console', 'file'],
            'level': LOG_LEVEL,
        },
        'jumpserver.users.api': {
            'handlers': ['console', 'file'],
            'level': LOG_LEVEL,
        },
        'jumpserver.users.view': {
            'handlers': ['console', 'file'],
            'level': LOG_LEVEL,
226
        },
A
Administrator 已提交
227 228
        'ops.ansible_api': {
            'handlers': ['console', 'ansible_logs'],
229
            'level': LOG_LEVEL,
W
wangyong 已提交
230 231 232
        }
    }
}
baltery's avatar
baltery 已提交
233 234 235 236

# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/

baltery's avatar
baltery 已提交
237
LANGUAGE_CODE = 'en-us'
baltery's avatar
baltery 已提交
238 239 240 241 242 243 244 245 246

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True

baltery's avatar
baltery 已提交
247
# I18N translation
baltery's avatar
baltery 已提交
248
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale'), ]
baltery's avatar
baltery 已提交
249

baltery's avatar
baltery 已提交
250 251 252 253
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'
W
wangyong 已提交
254

baltery's avatar
baltery 已提交
255 256 257
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)
baltery's avatar
baltery 已提交
258

W
wangyong 已提交
259 260 261 262 263 264 265
# Media files (File, ImageField) will be save these

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/') + '/'

# Use django-bootstrap-form to format template, input max width arg
baltery's avatar
baltery 已提交
266
# BOOTSTRAP_COLUMN_COUNT = 11
W
wangyong 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283

# Init data or generate fake data source for development
FIXTURE_DIRS = [os.path.join(BASE_DIR, 'fixtures'), ]

# Email config
EMAIL_HOST = CONFIG.EMAIL_HOST
EMAIL_PORT = CONFIG.EMAIL_PORT
EMAIL_HOST_USER = CONFIG.EMAIL_HOST_USER
EMAIL_HOST_PASSWORD = CONFIG.EMAIL_HOST_PASSWORD
EMAIL_USE_SSL = CONFIG.EMAIL_USE_SSL
EMAIL_USE_TLS = CONFIG.EMAIL_USE_TLS
EMAIL_SUBJECT_PREFIX = CONFIG.EMAIL_SUBJECT_PREFIX

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': (
baltery's avatar
baltery 已提交
284
        'users.permissions.IsSuperUser',
W
wangyong 已提交
285 286
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
baltery's avatar
baltery 已提交
287
        'users.authentication.AccessKeyAuthentication',
288
        'users.authentication.AccessTokenAuthentication',
289
        'users.authentication.PrivateTokenAuthentication',
baltery's avatar
baltery 已提交
290
        'users.authentication.SessionAuthentication',
W
wangyong 已提交
291
    ),
baltery's avatar
baltery 已提交
292
    # 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
W
wangyong 已提交
293
}
江世峰 已提交
294

W
wangyong 已提交
295 296 297 298 299 300 301
# Custom User Auth model
AUTH_USER_MODEL = 'users.User'

# Celery using redis as broker
BROKER_URL = 'redis://%(password)s%(host)s:%(port)s/3' % {
    'password': CONFIG.REDIS_PASSWORD + ':' if CONFIG.REDIS_PASSWORD else '',
    'host': CONFIG.REDIS_HOST or '127.0.0.1',
U
unknown 已提交
302
    'port': CONFIG.REDIS_PORT or 6379,
W
wangyong 已提交
303 304
}
CELERY_RESULT_BACKEND = BROKER_URL
baltery's avatar
baltery 已提交
305

baltery's avatar
baltery 已提交
306 307 308 309
# TERMINAL_HEATBEAT_INTERVAL = CONFIG.TERMINAL_HEATBEAT_INTERVAL or 30

# crontab job
# CELERYBEAT_SCHEDULE = {
310
#     Check applications is alive every 10m
311 312 313 314 315
# 'check_terminal_alive': {
#     'task': 'applications.tasks.check_terminal_alive',
#     'schedule': timedelta(seconds=TERMINAL_HEATBEAT_INTERVAL),
#     'args': (),
# },
baltery's avatar
baltery 已提交
316 317 318
# }


baltery's avatar
baltery 已提交
319 320 321 322 323 324 325 326 327 328 329 330
# Cache use redis
CACHES = {
    'default': {
        'BACKEND': 'redis_cache.RedisCache',
        'LOCATION': 'redis://%(password)s%(host)s:%(port)s/4' % {
            'password': CONFIG.REDIS_PASSWORD + '@' if CONFIG.REDIS_PASSWORD else '',
            'host': CONFIG.REDIS_HOST or '127.0.0.1',
            'port': CONFIG.REDIS_PORT or 6379,
        }
    }
}

baltery's avatar
baltery 已提交
331
# Captcha settings, more see https://django-simple-captcha.readthedocs.io/en/latest/advanced.html
baltery's avatar
baltery 已提交
332
CAPTCHA_IMAGE_SIZE = (80, 33)
baltery's avatar
baltery 已提交
333
CAPTCHA_FOREGROUND_COLOR = '#001100'
baltery's avatar
baltery 已提交
334
CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_dots',)
baltery's avatar
baltery 已提交
335
CAPTCHA_TEST_MODE = CONFIG.CAPTCHA_TEST_MODE
baltery's avatar
i18n  
baltery 已提交
336

337
COMMAND_STORE_BACKEND = 'audits.backends.command.db'
baltery's avatar
baltery 已提交
338
RECORD_STORE_BACKEND = 'audits.backends.record.db'
339 340 341 342 343 344 345 346 347 348


# Django bootstrap3 setting, more see http://django-bootstrap3.readthedocs.io/en/latest/settings.html
BOOTSTRAP3 = {
    'horizontal_label_class': 'col-md-2',
    # Field class to use in horizontal forms
    'horizontal_field_class': 'col-md-9',
    # Set placeholder attributes to label if no placeholder is provided
    'set_placeholder': True,
}