diff --git a/MANIFEST.in b/MANIFEST.in index 6419431..304a919 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,6 @@ include MANIFEST.in include VERSION -include mandaye/alembic.ini +include mandaye/alembic.ini mandaye/default-config.ini recursive-include mandaye/alembic * recursive-include mandaye/templates *.html diff --git a/mandaye/__init__.py b/mandaye/__init__.py index 8f6e596..2ce1e95 100644 --- a/mandaye/__init__.py +++ b/mandaye/__init__.py @@ -1,21 +1 @@ __version__='0.10.2' - -import os - -from importlib import import_module - -from mandaye import global_config -from mandaye.exceptions import ImproperlyConfigured - -ENVIRONMENT_VARIABLE = "MANDAYE_CONFIG_MODULE" -config = None - -if os.environ.has_key(ENVIRONMENT_VARIABLE): - try: - mod = import_module(os.environ[ENVIRONMENT_VARIABLE]) - except ImportError, e: - raise ImproperlyConfigured('Error importing config %s: "%s"' % (os.environ[ENVIRONMENT_VARIABLE], e)) - config = mod -else: - config = global_config - diff --git a/mandaye/skel/example.module/config.py b/mandaye/config.py similarity index 72% rename from mandaye/skel/example.module/config.py rename to mandaye/config.py index 68ba259..25a833d 100644 --- a/mandaye/skel/example.module/config.py +++ b/mandaye/config.py @@ -1,98 +1,98 @@ -import logging import os from ConfigParser import SafeConfigParser from mandaye.exceptions import ImproperlyConfigured +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + # get configuration files from : # 1. default-settings.ini from source code -# 2. os.environ.get('SETTINGS_INI') if it exists -# else /etc/mandaye-cam/config.ini -# and then /etc/mandaye-cam/local-config.ini -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -SETTINGS_INI = (os.path.join(BASE_DIR, 'default-config.ini'),) -if os.environ.get('SETTINGS_INI'): - SETTINGS_INI += (os.environ.get('SETTINGS_INI'),) -else: - ETC_DIR = os.path.join('/', 'etc', 'mandaye-cam') - SETTINGS_INI += ( - os.path.join(ETC_DIR, 'config.ini'), - os.path.join(ETC_DIR, 'local-config.ini') - ) - +# 2. from MANDAYE_CONFIG_FILE environ variable +SETTINGS_INI = [os.path.join(BASE_DIR, 'default-config.ini')] +if 'MANDAYE_CONFIG_FILES' in os.environ: + print 'Loading setting files %r' % os.environ['MANDAYE_CONFIG_FILES'] + SETTINGS_INI += os.environ['MANDAYE_CONFIG_FILES'].split(' ') config = SafeConfigParser() config.read(SETTINGS_INI) + +def section2dict(section): + res = dict() + if config.has_section(section): + for opt in config.options(section): + res[opt] = config.get(section, opt) + return res + ## SQL Backend config # Database configuration -# http://docs.sqlalchemy.org/en/rel_0_7/core/engines.html -# rfc 1738 https://tools.ietf.org/html/rfc1738 # dialect+driver://username:password@host:port/database db_url = config.get('database', 'url') ## LDAP Backend config ldap_url = config.get('ldap', 'url') -ldap_bind_dn = config.get('ldap', 'base_dn') +ldap_bind_dn = config.get('ldap', 'bind_dn') ldap_bind_password = config.get('ldap', 'bind_password') ldap_base_dn = config.get('ldap', 'base_dn') debug = config.getboolean('debug', 'debug') # Log configuration -LOGGING = {{ +logger_name = config.get('debug', 'logger_name') +LOGGING = { 'version': 1, 'disable_existing_loggers': True, - 'formatters': {{ - 'console': {{ + 'formatters': { + 'console': { 'format': '%(asctime)s %(levelname)s %(message)s', 'datefmt': '%H:%M:%S', - }}, - 'file': {{ - 'format': '%(asctime)s %(levelname)s %(uuid)s %(message)s', + }, + 'syslog': { + 'format': 'mandaye(pid=%(process)d) %(name)s %(levelname)s %(uuid)s %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S' - }} - }}, - 'handlers': {{ - 'console': {{ + } + }, + 'handlers': { + 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'console' - }}, - 'syslog': {{ + }, + 'syslog': { 'level': 'DEBUG', 'class': 'entrouvert.logging.handlers.SysLogHandler', - 'formatter': 'file', + 'formatter': 'syslog', 'address': '/dev/log' - }}, - }}, - 'loggers': {{ - '': {{ + }, + }, + 'loggers': { + '': { 'handlers': ['console'], 'level': 'INFO', 'propagate': False, - }}, - 'mandaye': {{ + }, + 'mandaye': { 'handlers': ['console', 'syslog'], 'level': 'INFO', 'propagate': False, - }}, - 'cam': {{ + }, + logger_name: { 'handlers': ['console', 'syslog'], 'level': 'INFO', 'propagate': False, - }}, - }}, - }} + }, + }, + } if config.getboolean('debug', 'log_debug'): LOGGING['loggers']['']['level'] = 'DEBUG' LOGGING['loggers']['mandaye']['level'] = 'DEBUG' - LOGGING['loggers']['cam']['level'] = 'DEBUG' + LOGGING['loggers'][logger_name]['level'] = 'DEBUG' ## PATH # Configuration directory config_root = config.get('dirs', 'config_root') +template_directory = os.path.join(BASE_DIR, 'templates') # Templates directories templates_directories = [] if config.get('dirs', 'templates_directories'): @@ -104,22 +104,16 @@ static_url = config.get('dirs', 'static_url') static_root = config.get('dirs', 'static_root') # Data dir data_dir = config.get('dirs', 'data_dir') +skel_root = os.path.join(BASE_DIR, 'skel') # template vars -template_vars = {{}} -if config.has_section('template_vars'): - for option in config.options('template_vars'): - template_vars[option] = config.get('template_vars', option) +template_vars = section2dict('template_vars') # Supported authentification -authentifications = {{ - 'saml2': 'mandaye.auth.saml2.SAML2Auth' -}} +authentifications = section2dict('authentifications') # sp mappers -mappers = {{ - 'linuxfr': '{project_name}.mappers.linuxfr_example', -}} +mappers = section2dict('mappers') # Raven Sentry configuration raven_dsn = config.get('debug', 'sentry_dsn') @@ -132,6 +126,10 @@ smtp_port = config.getint('email', 'smtp_port') email_from = config.get('email', 'from') email_to = config.get('email', 'to').split() +# Alembic configuration +alembic_cfg = os.path.join(BASE_DIR, 'alembic.ini') +alembic_script_path = os.path.join(BASE_DIR, 'alembic') + # Use long traceback with xtraceback use_long_trace = config.getboolean('debug', 'use_long_trace') # Ask Mandaye to auto decompress a response message @@ -164,18 +162,17 @@ if session_type == 'memcached': session_type = 'ext:memcached' # Beaker session configuration -session_opts = {{ +session_opts = { 'session.type': session_type, 'session.url': config.get('session', 'url'), 'session.cookie_expires': config.getboolean('session', 'cookie_expires'), 'session.timeout': config.getint('session', 'timeout'), - 'session.data_dir': config.get('session', 'data_dir'), - 'session.path': '/' -}} + 'session.data_dir': config.get('session', 'data_dir') +} # Import local config try: - from cam.local_config import * + from local_config import * except ImportError, e: if not 'local_config' in e.args[0]: raise ImproperlyConfigured('Error while importing "local_config.py"') diff --git a/mandaye/default-config.ini b/mandaye/default-config.ini new file mode 100644 index 0000000..c9aee2d --- /dev/null +++ b/mandaye/default-config.ini @@ -0,0 +1,68 @@ +[DEFAULT] +base_dir: . + +[database] +; http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html +url: sqlite:///%(base_dir)s/mandaye.db + +[ldap] +; use by ldap backend +url: ldap://127.0.0.1 +bind_dn: cn=admin,dc=acompany,dc=org +bind_password: AdminPassword +base_dn: ou=mandaye,dc=acompany,dc=org + +[dirs] +config_root: %(base_dir)s/conf.d +data_dir: %(base_dir)s/data +static_root: %(base_dir)s/mandaye/static +static_url: /mandaye/static +templates_directories: + +[debug] +debug: false +use_long_trace: true +log_debug: false +logger_name: mandaye +; you need to install python-raven for this feature +sentry_dsn: + +[mandaye] +toolbar: true +offline_toolbar: false +a2_auto_connection: true +; sql or ldap +storage_backend: ldap +auto_decompress: true +; if you want to encypt password set to true +; you need to install pycrypto for this feature +encrypt_sp_password: false +; if encrypt_sp_password then you need to choose a secret +; must be a 16, 24, or 32 bytes long +encrypt_secret: + +[template_vars] +; my_var: toto + +[authentifications] +saml2: mandaye.auth.saml2.SAML2Auth + +[mappers] +; my_mapper: mandaye_toto.mappers.titi + +[session] +; file, dbm, memory or memcached +; if memcached you need to install python-memcached and memcached +type: memcached +url: 127.0.0.1:11211 +cookie_expires: true +timeout: 3600 +data_dir: %(base_dir)s/data + +[email] +notification: false +prefix: [Mandaye] +smtp_host: localhost +smtp_port: 25 +from: traceback@example.com +to: admin+mandaye@example.com diff --git a/mandaye/global_config.py b/mandaye/global_config.py deleted file mode 100644 index 6080777..0000000 --- a/mandaye/global_config.py +++ /dev/null @@ -1,144 +0,0 @@ - -import os - -_PROJECT_PATH = os.path.join(os.path.dirname(__file__), '..') - -# Choose storage -# mandaye.backends.ldap_back or mandaye.backends.sql -storage_backend = "mandaye.backends.sql" - -## SQL Backend config -# Database configuration -# http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html -# rfc 1738 https://tools.ietf.org/html/rfc1738 -# dialect+driver://username:password@host:port/database -db_url = 'sqlite:///test.db' - -## LDAP Backend config -ldap_url = 'ldap://127.0.0.1' -ldap_bind_dn = 'cn=admin,dc=acompany,dc=org' -ldap_bind_password = 'MyPassword' -ldap_base_dn = 'ou=mandaye,dc=acompany,dc=org' - -# urllib2 debug mode -debug = False - -# Log configuration -LOGGING = { - 'version': 1, - 'disable_existing_loggers': True, - - 'formatters': { - 'console': { - 'format': '%(asctime)s %(levelname)s %(message)s', - 'datefmt': '%H:%M:%S', - }, - 'syslog': { - 'format': '%(name)s %(levelname)s %(uuid)s %(message)s', - } - }, - 'handlers': { - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'console' - }, - 'syslog': { - 'level': 'INFO', - 'class': 'entrouvert.logging.handlers.SysLogHandler', - 'formatter': 'syslog', - 'address': '/dev/log', - 'max_length': 999, - }, - }, - 'loggers': { - '': { - 'handlers': ['console'], - 'level': 'DEBUG', - 'propagate': False, - }, - 'mandaye': { - 'handlers': ['console', 'syslog'], - 'level': 'DEBUG', - 'propagate': False, - }, - }, - } - -# Template directory -template_directory = os.path.join(_PROJECT_PATH, 'mandaye/templates') -templates_directories = [] -# Configuration directory -config_root = os.path.join(_PROJECT_PATH, 'conf.d') -# Static path -static_url = '/mandaye/static' -# Static folder -static_root = os.path.join(_PROJECT_PATH, 'mandaye/static') -# Data dir -data_dir = os.path.join(_PROJECT_PATH, 'data') -# Skel root -skel_root = os.path.join(_PROJECT_PATH, 'mandaye/skel') - -# Raven Sentry configuration -raven_dsn = None - -# Email notification configuration -email_notification = False -email_prefix='[Mandaye]' -smtp_host = 'localhost' -smtp_port = 25 -email_from = 'traceback@entrouvert.com' -email_to = ['admin@localhost'] - -# Template vars -template_vars = {} - -# Use long traceback with xtraceback -use_long_trace = True -# Ask Mandaye to auto decompress a response message -# Decompress response only if you load a filter -auto_decompress = True -# Ask mandaye to add a toolbar -mandaye_toolbar = True -mandaye_offline_toolbar = False -# Authentic 2 auto connection -a2_auto_connection = False - -# Encrypt service provider passwords with a secret -# You should install pycypto to use this feature -encrypt_sp_password = False -# Must be a 16, 24, or 32 bytes long -encrypt_secret = '' - -alembic_cfg = os.path.join(_PROJECT_PATH, 'mandaye/alembic.ini') -alembic_script_path = os.path.join(_PROJECT_PATH, 'mandaye/alembic') - -# supported authentification -authentifications = { - 'saml2': 'mandaye.auth.SAML2Auth' - } - -# supported mappers -mappers = {} - -# beaker session configuration -session_opts = { - 'session.type': 'file', - 'session.cookie_expires': True, - 'session.timeout': 3600, - 'session.data_dir': '/var/tmp/beaker', - 'session.path': '/' - } - -# Needed if ssl is activated -ssl = False -keyfile = '' -certfile = '' - -if raven_dsn: - LOGGING['handlers']['sentry'] = { - 'level': 'ERROR', - 'class': 'raven.handlers.logging.SentryHandler', - 'dsn': raven_dsn, - } - LOGGING['loggers']['']['handlers'].append('sentry') diff --git a/mandaye/skel/example.module/__init__.py b/mandaye/skel/example.module/__init__.py index 40692a7..9476a7a 100644 --- a/mandaye/skel/example.module/__init__.py +++ b/mandaye/skel/example.module/__init__.py @@ -1 +1,6 @@ __version__="0.1.0" + +import os + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +default_config = os.path.join(BASE_DIR, 'default-config.ini') diff --git a/mandaye/skel/example.module/default-config.ini b/mandaye/skel/example.module/default-config.ini index 5be6b17..ad97bd1 100644 --- a/mandaye/skel/example.module/default-config.ini +++ b/mandaye/skel/example.module/default-config.ini @@ -24,6 +24,7 @@ templates_directories: debug: false use_long_trace: true log_debug: false +logger_name: {project_name} ; you need to install python-raven for this feature sentry_dsn: @@ -52,7 +53,7 @@ data_dir: %(base_dir)s/data [email] notification: false -prefix: [Mandaye CAM] +prefix: [Mandaye-{project_name}] smtp_host: localhost smtp_port: 25 from: traceback@entrouvert.com diff --git a/mandaye/skel/example.module/wsgi.py b/mandaye/skel/example.module/wsgi.py index a4a1880..fcfcee2 100644 --- a/mandaye/skel/example.module/wsgi.py +++ b/mandaye/skel/example.module/wsgi.py @@ -1,14 +1,18 @@ import os +from {project_name} import default_config -os.environ.setdefault("MANDAYE_CONFIG_MODULE", "{project_name}.config") +if os.environ.has_key('MANDAYE_CONFIG_FILES'): + os.environ['MANDAYE_CONFIG_FILES'] = default_config + ' ' + \ + os.environ['MANDAYE_CONFIG_FILES'] +else: + os.environ['MANDAYE_CONFIG_FILES'] = default_config from beaker.middleware import SessionMiddleware from whitenoise import WhiteNoise -from {project_name} import config - import mandaye +from mandaye import config from mandaye.server import MandayeApp # production diff --git a/mandaye/skel/local_config.py.example b/mandaye/skel/local_config.py.example deleted file mode 100644 index a88f84d..0000000 --- a/mandaye/skel/local_config.py.example +++ /dev/null @@ -1,20 +0,0 @@ -## Virtual hosts configuration -hosts = {{ - 'linuxfrsaml.local:8000': [ - {{ - 'path': r'/', - 'target': 'http://linuxfr.org', - 'mapping': '{project_name}.configs.linuxfr_saml_example.linuxfr_mapping' - }}, - ], - - }} - -## SQL Backend config -# http://docs.sqlalchemy.org/en/rel_0_7/core/engines.html -# rfc 1738 https://tools.ietf.org/html/rfc1738 -# dialect+driver://username:password@host:port/database -db_url = 'sqlite:///test.db' - -## Logging configuration -debug = False diff --git a/mandaye/skel/manager.py b/mandaye/skel/manager.py index 34a32b1..16df419 100755 --- a/mandaye/skel/manager.py +++ b/mandaye/skel/manager.py @@ -5,18 +5,18 @@ """ import os -os.environ['MANDAYE_CONFIG_MODULE'] = '{project_name}.config' - -import base64 from optparse import OptionParser - -from mandaye import config -from mandaye.log import logger +from {project_name} import default_config def get_cmd_options(): - usage = "usage: %prog --createdb|--upgradedb|--cryptpwd" + usage = "usage: %prog --config=/path/to/config.ini --createdb|--upgradedb" parser = OptionParser(usage=usage) + parser.add_option("--config", + dest="config", + type="string", + help="Path of the configuration file" + ) parser.add_option("--createdb", dest="createdb", default=False, @@ -29,48 +29,27 @@ def get_cmd_options(): action="store_true", help="Upgrade Mandaye database" ) - parser.add_option("--cryptpwd", - dest="cryptpwd", - default=False, - action="store_true", - help="Crypt external password in Mandaye's database" - ) (options, args) = parser.parse_args() return options -def encrypt_pwd(pwd): - from Crypto.Cipher import AES - logger.debug("Encrypt password") - enc_pwd = pwd - if config.encrypt_secret: - try: - cipher = AES.new(config.encrypt_secret, AES.MODE_CFB) - enc_pwd = cipher.encrypt(pwd) - enc_pwd = base64.b64encode(enc_pwd) - except Exception, e: - if config.debug: - traceback.print_exc() - logger.warning('Password encrypting failed %s' % e) - else: - logger.warning("You must set a secret to use pwd encryption") - return enc_pwd - def main(): options = get_cmd_options() + + config_files = [default_config] + if options.config: + config_files.append(options.config) + os.environ['MANDAYE_CONFIG_FILES'] = ' '.join(config_files) + + from mandaye import config + from mandaye.log import logger if options.createdb or options.upgradedb: logger.info("Creating or upgrading database...") from alembic.config import Config from alembic import command - from mandaye import global_config - alembic_cfg = Config(global_config.alembic_cfg) - alembic_cfg.set_main_option("script_location", global_config.alembic_script_path) + alembic_cfg = Config(config.alembic_cfg) + alembic_cfg.set_main_option("script_location", config.alembic_script_path) command.upgrade(alembic_cfg, "head") logger.info("Database upgraded") - if options.cryptpwd: - from mandaye.backends.default import ManagerSPUser - for user in ManagerSPUser.all(): - user.password = encrypt_pwd(user.password) - ManagerSPUser.save() if __name__ == "__main__": main() diff --git a/mandaye/skel/server.py b/mandaye/skel/server.py index 5db3290..6bb71aa 100755 --- a/mandaye/skel/server.py +++ b/mandaye/skel/server.py @@ -5,11 +5,8 @@ """ import os -os.environ.setdefault("MANDAYE_CONFIG_MODULE", "{project_name}.config") - import sys -from mandaye.log import logger from gunicorn.app.wsgiapp import WSGIApplication class MandayeWSGIApplication(WSGIApplication): @@ -22,7 +19,16 @@ def main(): """ The ``gunicorn`` command line runner for launcing Gunicorn with generic WSGI applications. """ - logger.info('{project_name} reverse-proxy start') + config_file = None + config_arg_pos = None + for i, arg in enumerate(sys.argv[1:]): + if arg.startswith('--config='): + config_file = arg.split('=')[1] + config_arg_pos = i + if config_file: + os.environ['MANDAYE_CONFIG_FILES'] = config_file + if config_arg_pos is not None: + del sys.argv[config_arg_pos + 1] MandayeWSGIApplication("%(prog)s [OPTIONS]").run() if __name__ == "__main__": diff --git a/mandaye/template.py b/mandaye/template.py index 846109a..9fcde94 100644 --- a/mandaye/template.py +++ b/mandaye/template.py @@ -2,9 +2,9 @@ from mako.lookup import TemplateLookup from mako.template import Template -from mandaye import config, global_config +from mandaye import config -templates_directories = config.templates_directories + [global_config.template_directory] +templates_directories = config.templates_directories + [config.template_directory] mylookup = TemplateLookup(directories=templates_directories, input_encoding='utf-8') diff --git a/scripts/mandaye-admin.py b/scripts/mandaye-admin.py index 083b574..5641925 100755 --- a/scripts/mandaye-admin.py +++ b/scripts/mandaye-admin.py @@ -11,7 +11,7 @@ import sys from optparse import OptionParser -from mandaye import config, global_config +from mandaye import config from mandaye.log import logger def get_cmd_options(): @@ -39,7 +39,7 @@ def main(): project_name) modue_example = os.path.join(project_name, "example.module") - skel = global_config.skel_root + skel = config.skel_root logger.info("Creating project %s ..." % project_name) if os.path.exists(project_name): print "%s folder already exist" % project_name