[mod] proposition to remove globals magic

This commit is contained in:
Laurent Peuch 2017-07-25 16:18:09 +02:00
parent e6cffbc3e2
commit 863c3dd050
10 changed files with 118 additions and 105 deletions

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from moulinette.core import init_interface, MoulinetteError from moulinette.core import init_interface, MoulinetteError, MoulinetteSignals
__title__ = 'moulinette' __title__ = 'moulinette'
__version__ = '0.1' __version__ = '0.1'
@ -31,6 +31,11 @@ __all__ = [
'init_interface', 'MoulinetteError', 'init_interface', 'MoulinetteError',
] ]
msignals = MoulinetteSignals()
msettings = dict()
pkg = None
m18n = None
# Package functions # Package functions
@ -50,21 +55,16 @@ def init(logging_config=None, **kwargs):
""" """
import sys import sys
import __builtin__ from moulinette.core import Package, Moulinette18n
from moulinette.core import (
Package, Moulinette18n, MoulinetteSignals
)
from moulinette.utils.log import configure_logging from moulinette.utils.log import configure_logging
configure_logging(logging_config) configure_logging(logging_config)
pkg = Package(**kwargs) global pkg, m18n
# Define and instantiate global objects # Define and instantiate global objects
__builtin__.__dict__['pkg'] = pkg pkg = Package(**kwargs)
__builtin__.__dict__['m18n'] = Moulinette18n(pkg) m18n = Moulinette18n(pkg)
__builtin__.__dict__['msignals'] = MoulinetteSignals()
__builtin__.__dict__['msettings'] = dict()
# Add library directory to python path # Add library directory to python path
sys.path.insert(0, pkg.libdir) sys.path.insert(0, pkg.libdir)

View file

@ -9,6 +9,7 @@ import cPickle as pickle
from time import time from time import time
from collections import OrderedDict from collections import OrderedDict
import moulinette
from moulinette.core import (MoulinetteError, MoulinetteLock) from moulinette.core import (MoulinetteError, MoulinetteLock)
from moulinette.interfaces import ( from moulinette.interfaces import (
BaseActionsMapParser, GLOBAL_SECTION, TO_RETURN_PROP BaseActionsMapParser, GLOBAL_SECTION, TO_RETURN_PROP
@ -98,7 +99,7 @@ class AskParameter(_ExtraParameter):
try: try:
# Ask for the argument value # Ask for the argument value
return msignals.prompt(m18n.n(message)) return moulinette.msignals.prompt(moulinette.m18n.n(message))
except NotImplementedError: except NotImplementedError:
return arg_value return arg_value
@ -131,7 +132,7 @@ class PasswordParameter(AskParameter):
try: try:
# Ask for the password # Ask for the password
return msignals.prompt(m18n.n(message), True, True) return moulinette.msignals.prompt(moulinette.m18n.n(message), True, True)
except NotImplementedError: except NotImplementedError:
return arg_value return arg_value
@ -160,12 +161,12 @@ class PatternParameter(_ExtraParameter):
v, arg_name, pattern) v, arg_name, pattern)
# Attempt to retrieve message translation # Attempt to retrieve message translation
msg = m18n.n(message) msg = moulinette.m18n.n(message)
if msg == message: if msg == message:
msg = m18n.g(message) msg = moulinette.m18n.g(message)
raise MoulinetteError(errno.EINVAL, raise MoulinetteError(errno.EINVAL,
m18n.g('invalid_argument', moulinette.m18n.g('invalid_argument',
argument=arg_name, error=msg)) argument=arg_name, error=msg))
return arg_value return arg_value
@ -196,7 +197,7 @@ class RequiredParameter(_ExtraParameter):
logger.debug("argument '%s' is required", logger.debug("argument '%s' is required",
arg_name) arg_name)
raise MoulinetteError(errno.EINVAL, raise MoulinetteError(errno.EINVAL,
m18n.g('argument_required', moulinette.m18n.g('argument_required',
argument=arg_name)) argument=arg_name))
return arg_value return arg_value
@ -261,7 +262,7 @@ class ExtraArgumentParser(object):
except Exception as e: except Exception as e:
logger.error("unable to validate extra parameter '%s' " logger.error("unable to validate extra parameter '%s' "
"for argument '%s': %s", p, arg_name, e) "for argument '%s': %s", p, arg_name, e)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
return parameters return parameters
@ -373,10 +374,10 @@ class ActionsMap(object):
for n in namespaces: for n in namespaces:
logger.debug("loading actions map namespace '%s'", n) logger.debug("loading actions map namespace '%s'", n)
actionsmap_yml = '%s/actionsmap/%s.yml' % (pkg.datadir, n) actionsmap_yml = '%s/actionsmap/%s.yml' % (moulinette.pkg.datadir, n)
actionsmap_yml_stat = os.stat(actionsmap_yml) actionsmap_yml_stat = os.stat(actionsmap_yml)
actionsmap_pkl = '%s/actionsmap/%s-%d-%d.pkl' % ( actionsmap_pkl = '%s/actionsmap/%s-%d-%d.pkl' % (
pkg.cachedir, moulinette.pkg.cachedir,
n, n,
actionsmap_yml_stat.st_size, actionsmap_yml_stat.st_size,
actionsmap_yml_stat.st_mtime actionsmap_yml_stat.st_mtime
@ -399,7 +400,7 @@ class ActionsMap(object):
actionsmaps[n] = ordered_yaml_load(f) actionsmaps[n] = ordered_yaml_load(f)
# Load translations # Load translations
m18n.load_namespace(n) moulinette.m18n.load_namespace(n)
# Generate parsers # Generate parsers
self.extraparser = ExtraArgumentParser(parser_class.interface) self.extraparser = ExtraArgumentParser(parser_class.interface)
@ -466,7 +467,7 @@ class ActionsMap(object):
except (AttributeError, ImportError): except (AttributeError, ImportError):
logger.exception("unable to load function %s.%s.%s", logger.exception("unable to load function %s.%s.%s",
namespace, category, func_name) namespace, category, func_name)
raise MoulinetteError(errno.EIO, m18n.g('error_see_log')) raise MoulinetteError(errno.EIO, moulinette.m18n.g('error_see_log'))
else: else:
log_id = start_action_logging() log_id = start_action_logging()
if logger.isEnabledFor(logging.DEBUG): if logger.isEnabledFor(logging.DEBUG):
@ -478,7 +479,7 @@ class ActionsMap(object):
log_id, namespace, category, action) log_id, namespace, category, action)
# Load translation and process the action # Load translation and process the action
m18n.load_namespace(namespace) moulinette.m18n.load_namespace(namespace)
start = time() start = time()
try: try:
return func(**arguments) return func(**arguments)
@ -498,7 +499,7 @@ class ActionsMap(object):
""" """
namespaces = [] namespaces = []
for f in os.listdir('%s/actionsmap' % pkg.datadir): for f in os.listdir('%s/actionsmap' % moulinette.pkg.datadir):
if f.endswith('.yml'): if f.endswith('.yml'):
namespaces.append(f[:-4]) namespaces.append(f[:-4])
return namespaces return namespaces
@ -524,23 +525,23 @@ class ActionsMap(object):
logger.debug("generating cache for actions map namespace '%s'", n) logger.debug("generating cache for actions map namespace '%s'", n)
# Read actions map from yaml file # Read actions map from yaml file
am_file = '%s/actionsmap/%s.yml' % (pkg.datadir, n) am_file = '%s/actionsmap/%s.yml' % (moulinette.pkg.datadir, n)
with open(am_file, 'r') as f: with open(am_file, 'r') as f:
actionsmaps[n] = ordered_yaml_load(f) actionsmaps[n] = ordered_yaml_load(f)
# at installation, cachedir might not exists # at installation, cachedir might not exists
if os.path.exists('%s/actionsmap/' % pkg.cachedir): if os.path.exists('%s/actionsmap/' % moulinette.pkg.cachedir):
# clean old cached files # clean old cached files
for i in os.listdir('%s/actionsmap/' % pkg.cachedir): for i in os.listdir('%s/actionsmap/' % moulinette.pkg.cachedir):
if i.endswith(".pkl"): if i.endswith(".pkl"):
os.remove('%s/actionsmap/%s' % (pkg.cachedir, i)) os.remove('%s/actionsmap/%s' % (moulinette.pkg.cachedir, i))
# Cache actions map into pickle file # Cache actions map into pickle file
am_file_stat = os.stat(am_file) am_file_stat = os.stat(am_file)
pkl = '%s-%d-%d.pkl' % (n, am_file_stat.st_size, am_file_stat.st_mtime) pkl = '%s-%d-%d.pkl' % (n, am_file_stat.st_size, am_file_stat.st_mtime)
with pkg.open_cachefile(pkl, 'w', subdir='actionsmap') as f: with moulinette.pkg.open_cachefile(pkl, 'w', subdir='actionsmap') as f:
pickle.dump(actionsmaps[n], f) pickle.dump(actionsmaps[n], f)
return actionsmaps return actionsmaps

View file

@ -4,6 +4,7 @@ import errno
import gnupg import gnupg
import logging import logging
import moulinette
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
logger = logging.getLogger('moulinette.authenticator') logger = logging.getLogger('moulinette.authenticator')
@ -95,7 +96,7 @@ class BaseAuthenticator(object):
except TypeError: except TypeError:
logger.error("unable to extract token parts from '%s'", token) logger.error("unable to extract token parts from '%s'", token)
if password is None: if password is None:
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
logger.info("session will not be stored") logger.info("session will not be stored")
store_session = False store_session = False
@ -112,7 +113,7 @@ class BaseAuthenticator(object):
except: except:
logger.exception("authentication (name: '%s', vendor: '%s') fails", logger.exception("authentication (name: '%s', vendor: '%s') fails",
self.name, self.vendor) self.name, self.vendor)
raise MoulinetteError(errno.EACCES, m18n.g('unable_authenticate')) raise MoulinetteError(errno.EACCES, moulinette.m18n.g('unable_authenticate'))
# Store session # Store session
if store_session: if store_session:
@ -129,7 +130,7 @@ class BaseAuthenticator(object):
def _open_sessionfile(self, session_id, mode='r'): def _open_sessionfile(self, session_id, mode='r'):
"""Open a session file for this instance in given mode""" """Open a session file for this instance in given mode"""
return pkg.open_cachefile('%s.asc' % session_id, mode, return moulinette.pkg.open_cachefile('%s.asc' % session_id, mode,
subdir='session/%s' % self.name) subdir='session/%s' % self.name)
def _store_session(self, session_id, session_hash, password): def _store_session(self, session_id, session_hash, password):
@ -148,7 +149,7 @@ class BaseAuthenticator(object):
except IOError: except IOError:
logger.debug("unable to retrieve session", exc_info=1) logger.debug("unable to retrieve session", exc_info=1)
raise MoulinetteError(errno.ENOENT, raise MoulinetteError(errno.ENOENT,
m18n.g('unable_retrieve_session')) moulinette.m18n.g('unable_retrieve_session'))
else: else:
gpg = gnupg.GPG() gpg = gnupg.GPG()
gpg.encoding = 'utf-8' gpg.encoding = 'utf-8'
@ -158,5 +159,5 @@ class BaseAuthenticator(object):
logger.error("unable to decrypt password for the session: %s", logger.error("unable to decrypt password for the session: %s",
decrypted.status) decrypted.status)
raise MoulinetteError(errno.EINVAL, raise MoulinetteError(errno.EINVAL,
m18n.g('unable_retrieve_session')) moulinette.m18n.g('unable_retrieve_session'))
return decrypted.data return decrypted.data

View file

@ -7,6 +7,7 @@ import logging
import ldap import ldap
import ldap.modlist as modlist import ldap.modlist as modlist
import moulinette
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette.authenticators import BaseAuthenticator from moulinette.authenticators import BaseAuthenticator
@ -75,10 +76,10 @@ class Authenticator(BaseAuthenticator):
else: else:
con.simple_bind_s() con.simple_bind_s()
except ldap.INVALID_CREDENTIALS: except ldap.INVALID_CREDENTIALS:
raise MoulinetteError(errno.EACCES, m18n.g('invalid_password')) raise MoulinetteError(errno.EACCES, moulinette.m18n.g('invalid_password'))
except ldap.SERVER_DOWN: except ldap.SERVER_DOWN:
logger.exception('unable to reach the server to authenticate') logger.exception('unable to reach the server to authenticate')
raise MoulinetteError(169, m18n.g('ldap_server_down')) raise MoulinetteError(169, moulinette.m18n.g('ldap_server_down'))
else: else:
self.con = con self.con = con
@ -139,7 +140,7 @@ class Authenticator(BaseAuthenticator):
except: except:
logger.exception("error during LDAP add operation with: rdn='%s', " logger.exception("error during LDAP add operation with: rdn='%s', "
"attr_dict=%s", rdn, attr_dict) "attr_dict=%s", rdn, attr_dict)
raise MoulinetteError(169, m18n.g('ldap_operation_error')) raise MoulinetteError(169, moulinette.m18n.g('ldap_operation_error'))
else: else:
return True return True
@ -159,7 +160,7 @@ class Authenticator(BaseAuthenticator):
self.con.delete_s(dn) self.con.delete_s(dn)
except: except:
logger.exception("error during LDAP delete operation with: rdn='%s'", rdn) logger.exception("error during LDAP delete operation with: rdn='%s'", rdn)
raise MoulinetteError(169, m18n.g('ldap_operation_error')) raise MoulinetteError(169, moulinette.m18n.g('ldap_operation_error'))
else: else:
return True return True
@ -189,7 +190,7 @@ class Authenticator(BaseAuthenticator):
except: except:
logger.exception("error during LDAP update operation with: rdn='%s', " logger.exception("error during LDAP update operation with: rdn='%s', "
"attr_dict=%s, new_rdn=%s", rdn, attr_dict, new_rdn) "attr_dict=%s, new_rdn=%s", rdn, attr_dict, new_rdn)
raise MoulinetteError(169, m18n.g('ldap_operation_error')) raise MoulinetteError(169, moulinette.m18n.g('ldap_operation_error'))
else: else:
return True return True
@ -211,6 +212,6 @@ class Authenticator(BaseAuthenticator):
logger.info("attribute '%s' with value '%s' is not unique", logger.info("attribute '%s' with value '%s' is not unique",
attr, value) attr, value)
raise MoulinetteError(errno.EEXIST, raise MoulinetteError(errno.EEXIST,
m18n.g('ldap_attribute_already_exists', moulinette.m18n.g('ldap_attribute_already_exists',
attribute=attr, value=value)) attribute=attr, value=value))
return True return True

View file

@ -8,6 +8,8 @@ import logging
from importlib import import_module from importlib import import_module
import moulinette
logger = logging.getLogger('moulinette.core') logger = logging.getLogger('moulinette.core')
@ -450,7 +452,7 @@ def init_interface(name, kwargs={}, actionsmap={}):
mod = import_module('moulinette.interfaces.%s' % name) mod = import_module('moulinette.interfaces.%s' % name)
except ImportError: except ImportError:
logger.exception("unable to load interface '%s'", name) logger.exception("unable to load interface '%s'", name)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
else: else:
try: try:
# Retrieve interface classes # Retrieve interface classes
@ -458,7 +460,7 @@ def init_interface(name, kwargs={}, actionsmap={}):
interface = mod.Interface interface = mod.Interface
except AttributeError: except AttributeError:
logger.exception("unable to retrieve classes of interface '%s'", name) logger.exception("unable to retrieve classes of interface '%s'", name)
raise MoulinetteError(errno.EIO, m18n.g('error_see_log')) raise MoulinetteError(errno.EIO, moulinette.m18n.g('error_see_log'))
# Instantiate or retrieve ActionsMap # Instantiate or retrieve ActionsMap
if isinstance(actionsmap, dict): if isinstance(actionsmap, dict):
@ -467,7 +469,7 @@ def init_interface(name, kwargs={}, actionsmap={}):
amap = actionsmap amap = actionsmap
else: else:
logger.error("invalid actionsmap value %r", actionsmap) logger.error("invalid actionsmap value %r", actionsmap)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
return interface(amap, **kwargs) return interface(amap, **kwargs)
@ -488,7 +490,7 @@ def init_authenticator((vendor, name), kwargs={}):
mod = import_module('moulinette.authenticators.%s' % vendor) mod = import_module('moulinette.authenticators.%s' % vendor)
except ImportError: except ImportError:
logger.exception("unable to load authenticator vendor '%s'", vendor) logger.exception("unable to load authenticator vendor '%s'", vendor)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
else: else:
return mod.Authenticator(name, **kwargs) return mod.Authenticator(name, **kwargs)
@ -504,7 +506,7 @@ def clean_session(session_id, profiles=[]):
- profiles -- A list of profiles to clean - profiles -- A list of profiles to clean
""" """
sessiondir = pkg.get_cachedir('session') sessiondir = moulinette.pkg.get_cachedir('session')
if not profiles: if not profiles:
profiles = os.listdir(sessiondir) profiles = os.listdir(sessiondir)
@ -578,7 +580,7 @@ class MoulinetteLock(object):
if self.timeout is not None and (time.time() - start_time) > self.timeout: if self.timeout is not None and (time.time() - start_time) > self.timeout:
raise MoulinetteError(errno.EBUSY, raise MoulinetteError(errno.EBUSY,
m18n.g('instance_already_running')) moulinette.m18n.g('instance_already_running'))
# Wait before checking again # Wait before checking again
time.sleep(self.interval) time.sleep(self.interval)
@ -605,8 +607,8 @@ class MoulinetteLock(object):
except IOError: except IOError:
raise MoulinetteError( raise MoulinetteError(
errno.EPERM, '%s. %s.'.format( errno.EPERM, '%s. %s.'.format(
m18n.g('permission_denied'), moulinette.m18n.g('permission_denied'),
m18n.g('root_required'))) moulinette.m18n.g('root_required')))
def __enter__(self): def __enter__(self):
if not self._locked: if not self._locked:

View file

@ -7,6 +7,8 @@ import logging
import argparse import argparse
from collections import deque from collections import deque
import moulinette
from moulinette import msignals, msettings
from moulinette.core import (init_authenticator, MoulinetteError) from moulinette.core import (init_authenticator, MoulinetteError)
logger = logging.getLogger('moulinette.interface') logger = logging.getLogger('moulinette.interface')
@ -138,7 +140,7 @@ class BaseActionsMapParser(object):
# Validate tid and namespace # Validate tid and namespace
if not isinstance(tid, tuple) and \ if not isinstance(tid, tuple) and \
(namespace is None or not hasattr(namespace, TO_RETURN_PROP)): (namespace is None or not hasattr(namespace, TO_RETURN_PROP)):
raise MoulinetteError(errno.EINVAL, m18n.g('invalid_usage')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('invalid_usage'))
elif not tid: elif not tid:
tid = GLOBAL_SECTION tid = GLOBAL_SECTION
@ -159,7 +161,7 @@ class BaseActionsMapParser(object):
auth = msignals.authenticate(cls(), **auth_conf) auth = msignals.authenticate(cls(), **auth_conf)
if not auth.is_authenticated: if not auth.is_authenticated:
raise MoulinetteError(errno.EACCES, raise MoulinetteError(errno.EACCES,
m18n.g('authentication_required_long')) moulinette.m18n.g('authentication_required_long'))
if self.get_conf(tid, 'argument_auth') and \ if self.get_conf(tid, 'argument_auth') and \
self.get_conf(tid, 'authenticate') == 'all': self.get_conf(tid, 'authenticate') == 'all':
namespace.auth = auth namespace.auth = auth
@ -263,7 +265,7 @@ class BaseActionsMapParser(object):
else: else:
logger.error("expecting 'all', 'False' or a list for " logger.error("expecting 'all', 'False' or a list for "
"configuration 'authenticate', got %r", ifaces) "configuration 'authenticate', got %r", ifaces)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
# -- 'authenticator' # -- 'authenticator'
try: try:
@ -278,7 +280,7 @@ class BaseActionsMapParser(object):
except KeyError: except KeyError:
logger.error("requesting profile '%s' which is undefined in " logger.error("requesting profile '%s' which is undefined in "
"global configuration of 'authenticator'", auth) "global configuration of 'authenticator'", auth)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
elif is_global and isinstance(auth, dict): elif is_global and isinstance(auth, dict):
if len(auth) == 0: if len(auth) == 0:
logger.warning('no profile defined in global configuration ' logger.warning('no profile defined in global configuration '
@ -301,7 +303,7 @@ class BaseActionsMapParser(object):
else: else:
logger.error("expecting a dict of profile(s) or a profile name " logger.error("expecting a dict of profile(s) or a profile name "
"for configuration 'authenticator', got %r", auth) "for configuration 'authenticator', got %r", auth)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
# -- 'argument_auth' # -- 'argument_auth'
try: try:
@ -314,7 +316,7 @@ class BaseActionsMapParser(object):
else: else:
logger.error("expecting a boolean for configuration " logger.error("expecting a boolean for configuration "
"'argument_auth', got %r", arg_auth) "'argument_auth', got %r", arg_auth)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
# -- 'lock' # -- 'lock'
try: try:
@ -327,7 +329,7 @@ class BaseActionsMapParser(object):
else: else:
logger.error("expecting a boolean for configuration 'lock', " logger.error("expecting a boolean for configuration 'lock', "
"got %r", lock) "got %r", lock)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
return conf return conf
@ -427,7 +429,7 @@ class _CallbackAction(argparse.Action):
except: except:
logger.exception("cannot get value from callback method " logger.exception("cannot get value from callback method "
"'{0}'".format(self.callback_method)) "'{0}'".format(self.callback_method))
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
else: else:
if value: if value:
if self.callback_return: if self.callback_return:
@ -487,10 +489,10 @@ class _ExtendedSubParsersAction(argparse._SubParsersAction):
else: else:
# Warn the user about deprecated command # Warn the user about deprecated command
if correct_name is None: if correct_name is None:
logger.warning(m18n.g('deprecated_command', prog=parser.prog, logger.warning(moulinette.m18n.g('deprecated_command', prog=parser.prog,
command=parser_name)) command=parser_name))
else: else:
logger.warning(m18n.g('deprecated_command_alias', logger.warning(moulinette.m18n.g('deprecated_command_alias',
old=parser_name, new=correct_name, old=parser_name, new=correct_name,
prog=parser.prog)) prog=parser.prog))
values[0] = correct_name values[0] = correct_name

View file

@ -13,6 +13,8 @@ from geventwebsocket import WebSocketError
from bottle import run, request, response, Bottle, HTTPResponse from bottle import run, request, response, Bottle, HTTPResponse
import moulinette
from moulinette import msignals
from moulinette.core import MoulinetteError, clean_session from moulinette.core import MoulinetteError, clean_session
from moulinette.interfaces import ( from moulinette.interfaces import (
BaseActionsMapParser, BaseInterface, ExtendedArgumentParser, BaseActionsMapParser, BaseInterface, ExtendedArgumentParser,
@ -308,7 +310,7 @@ class _ActionsMapPlugin(object):
response.set_cookie('session.id', s_id, secure=True) response.set_cookie('session.id', s_id, secure=True)
response.set_cookie('session.hashes', s_hashes, secure=True, response.set_cookie('session.hashes', s_hashes, secure=True,
secret=s_secret) secret=s_secret)
return m18n.g('logged_in') return moulinette.m18n.g('logged_in')
def logout(self, profile=None): def logout(self, profile=None):
"""Log out from an authenticator profile """Log out from an authenticator profile
@ -324,13 +326,13 @@ class _ActionsMapPlugin(object):
try: try:
del self.secrets[s_id] del self.secrets[s_id]
except KeyError: except KeyError:
raise HTTPUnauthorizedResponse(m18n.g('not_logged_in')) raise HTTPUnauthorizedResponse(moulinette.m18n.g('not_logged_in'))
else: else:
# TODO: Clean the session for profile only # TODO: Clean the session for profile only
# Delete cookie and clean the session # Delete cookie and clean the session
response.set_cookie('session.hashes', '', max_age=-1) response.set_cookie('session.hashes', '', max_age=-1)
clean_session(s_id) clean_session(s_id)
return m18n.g('logged_out') return moulinette.m18n.g('logged_out')
def messages(self): def messages(self):
"""Listen to the messages WebSocket stream """Listen to the messages WebSocket stream
@ -350,7 +352,7 @@ class _ActionsMapPlugin(object):
wsock = request.environ.get('wsgi.websocket') wsock = request.environ.get('wsgi.websocket')
if not wsock: if not wsock:
raise HTTPErrorResponse(m18n.g('websocket_request_expected')) raise HTTPErrorResponse(moulinette.m18n.g('websocket_request_expected'))
while True: while True:
item = queue.get() item = queue.get()
@ -413,9 +415,9 @@ class _ActionsMapPlugin(object):
secret=s_secret)[authenticator.name] secret=s_secret)[authenticator.name]
except KeyError: except KeyError:
if authenticator.name == 'default': if authenticator.name == 'default':
msg = m18n.g('authentication_required') msg = moulinette.m18n.g('authentication_required')
else: else:
msg = m18n.g('authentication_profile_required', msg = moulinette.m18n.g('authentication_profile_required',
profile=authenticator.name) profile=authenticator.name)
raise HTTPUnauthorizedResponse(msg) raise HTTPUnauthorizedResponse(msg)
else: else:
@ -603,7 +605,7 @@ class ActionsMapParser(BaseActionsMapParser):
tid, parser = self._parsers[route] tid, parser = self._parsers[route]
except KeyError: except KeyError:
logger.error("no argument parser found for route '%s'", route) logger.error("no argument parser found for route '%s'", route)
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
ret = argparse.Namespace() ret = argparse.Namespace()
if not self.get_conf(tid, 'lock'): if not self.get_conf(tid, 'lock'):
@ -619,7 +621,7 @@ class ActionsMapParser(BaseActionsMapParser):
# TODO: Catch errors # TODO: Catch errors
auth = msignals.authenticate(klass(), **auth_conf) auth = msignals.authenticate(klass(), **auth_conf)
if not auth.is_authenticated: if not auth.is_authenticated:
raise MoulinetteError(errno.EACCES, m18n.g('authentication_required_long')) raise MoulinetteError(errno.EACCES, moulinette.m18n.g('authentication_required_long'))
if self.get_conf(tid, 'argument_auth') and \ if self.get_conf(tid, 'argument_auth') and \
self.get_conf(tid, 'authenticate') == 'all': self.get_conf(tid, 'authenticate') == 'all':
ret.auth = auth ret.auth = auth
@ -693,8 +695,8 @@ class Interface(BaseInterface):
try: try:
locale = request.params.pop('locale') locale = request.params.pop('locale')
except KeyError: except KeyError:
locale = m18n.default_locale locale = moulinette.m18n.default_locale
m18n.set_locale(locale) moulinette.m18n.set_locale(locale)
return callback return callback
# Install plugins # Install plugins
@ -742,8 +744,8 @@ class Interface(BaseInterface):
host, port) host, port)
if e.args[0] == errno.EADDRINUSE: if e.args[0] == errno.EADDRINUSE:
raise MoulinetteError(errno.EADDRINUSE, raise MoulinetteError(errno.EADDRINUSE,
m18n.g('server_already_running')) moulinette.m18n.g('server_already_running'))
raise MoulinetteError(errno.EIO, m18n.g('error_see_log')) raise MoulinetteError(errno.EIO, moulinette.m18n.g('error_see_log'))
# Routes handlers # Routes handlers
@ -756,11 +758,11 @@ class Interface(BaseInterface):
""" """
if category is None: if category is None:
with open('%s/../doc/resources.json' % pkg.datadir) as f: with open('%s/../doc/resources.json' % moulinette.pkg.datadir) as f:
return f.read() return f.read()
try: try:
with open('%s/../doc/%s.json' % (pkg.datadir, category)) as f: with open('%s/../doc/%s.json' % (moulinette.pkg.datadir, category)) as f:
return f.read() return f.read()
except IOError: except IOError:
return None return None

View file

@ -11,6 +11,8 @@ from collections import OrderedDict
import argcomplete import argcomplete
import moulinette
from moulinette import msignals
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette.interfaces import ( from moulinette.interfaces import (
BaseActionsMapParser, BaseInterface, ExtendedArgumentParser, BaseActionsMapParser, BaseInterface, ExtendedArgumentParser,
@ -183,7 +185,7 @@ class TTYHandler(logging.StreamHandler):
level = '%s ' % record.levelname level = '%s ' % record.levelname
elif record.levelname in ['SUCCESS', 'WARNING', 'ERROR']: elif record.levelname in ['SUCCESS', 'WARNING', 'ERROR']:
# add translated level name before message # add translated level name before message
level = '%s ' % m18n.g(record.levelname.lower()) level = '%s ' % moulinette.m18n.g(record.levelname.lower())
color = self.LEVELS_COLOR.get(record.levelno, 'white') color = self.LEVELS_COLOR.get(record.levelno, 'white')
msg = '{0}{1}{2}{3}'.format( msg = '{0}{1}{2}{3}'.format(
colors_codes[color], level, END_CLI_COLOR, msg) colors_codes[color], level, END_CLI_COLOR, msg)
@ -297,7 +299,7 @@ class ActionsMapParser(BaseActionsMapParser):
raise raise
except: except:
logger.exception("unable to parse arguments '%s'", ' '.join(args)) logger.exception("unable to parse arguments '%s'", ' '.join(args))
raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log'))
else: else:
self.prepare_action_namespace(getattr(ret, '_tid', None), ret) self.prepare_action_namespace(getattr(ret, '_tid', None), ret)
self._parser.dequeue_callbacks(ret) self._parser.dequeue_callbacks(ret)
@ -317,7 +319,7 @@ class Interface(BaseInterface):
def __init__(self, actionsmap): def __init__(self, actionsmap):
# Set user locale # Set user locale
m18n.set_locale(get_locale()) moulinette.m18n.set_locale(get_locale())
# Connect signals to handlers # Connect signals to handlers
msignals.set_handler('display', self._do_display) msignals.set_handler('display', self._do_display)
@ -344,7 +346,7 @@ class Interface(BaseInterface):
""" """
if output_as and output_as not in ['json', 'plain', 'none']: if output_as and output_as not in ['json', 'plain', 'none']:
raise MoulinetteError(errno.EINVAL, m18n.g('invalid_usage')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('invalid_usage'))
# auto-complete # auto-complete
argcomplete.autocomplete(self.actionsmap.parser._parser) argcomplete.autocomplete(self.actionsmap.parser._parser)
@ -357,7 +359,7 @@ class Interface(BaseInterface):
try: try:
ret = self.actionsmap.process(args, timeout=timeout) ret = self.actionsmap.process(args, timeout=timeout)
except (KeyboardInterrupt, EOFError): except (KeyboardInterrupt, EOFError):
raise MoulinetteError(errno.EINTR, m18n.g('operation_interrupted')) raise MoulinetteError(errno.EINTR, moulinette.m18n.g('operation_interrupted'))
if ret is None or output_as == 'none': if ret is None or output_as == 'none':
return return
@ -384,7 +386,7 @@ class Interface(BaseInterface):
""" """
# TODO: Allow token authentication? # TODO: Allow token authentication?
msg = m18n.n(help) if help else m18n.g('password') msg = moulinette.m18n.n(help) if help else moulinette.m18n.g('password')
return authenticator(password=self._do_prompt(msg, True, False, return authenticator(password=self._do_prompt(msg, True, False,
color='yellow')) color='yellow'))
@ -398,16 +400,16 @@ class Interface(BaseInterface):
""" """
if is_password: if is_password:
prompt = lambda m: getpass.getpass(colorize(m18n.g('colon', m), prompt = lambda m: getpass.getpass(colorize(moulinette.m18n.g('colon', m),
color)) color))
else: else:
prompt = lambda m: raw_input(colorize(m18n.g('colon', m), color)) prompt = lambda m: raw_input(colorize(moulinette.m18n.g('colon', m), color))
value = prompt(message) value = prompt(message)
if confirm: if confirm:
m = message[0].lower() + message[1:] m = message[0].lower() + message[1:]
if prompt(m18n.g('confirm', prompt=m)) != value: if prompt(moulinette.m18n.g('confirm', prompt=m)) != value:
raise MoulinetteError(errno.EINVAL, m18n.g('values_mismatch')) raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('values_mismatch'))
return value return value
@ -420,10 +422,10 @@ class Interface(BaseInterface):
if isinstance(message, unicode): if isinstance(message, unicode):
message = message.encode('utf-8') message = message.encode('utf-8')
if style == 'success': if style == 'success':
print('{} {}'.format(colorize(m18n.g('success'), 'green'), message)) print('{} {}'.format(colorize(moulinette.m18n.g('success'), 'green'), message))
elif style == 'warning': elif style == 'warning':
print('{} {}'.format(colorize(m18n.g('warning'), 'yellow'), message)) print('{} {}'.format(colorize(moulinette.m18n.g('warning'), 'yellow'), message))
elif style == 'error': elif style == 'error':
print('{} {}'.format(colorize(m18n.g('error'), 'red'), message)) print('{} {}'.format(colorize(moulinette.m18n.g('error'), 'red'), message))
else: else:
print(message) print(message)

View file

@ -5,6 +5,7 @@ import json
import grp import grp
from pwd import getpwnam from pwd import getpwnam
import moulinette
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
# Files & directories -------------------------------------------------- # Files & directories --------------------------------------------------
@ -22,7 +23,7 @@ def read_file(file_path):
# Check file exists # Check file exists
if not os.path.isfile(file_path): if not os.path.isfile(file_path):
raise MoulinetteError(errno.ENOENT, raise MoulinetteError(errno.ENOENT,
m18n.g('file_not_exist', path=file_path)) moulinette.m18n.g('file_not_exist', path=file_path))
# Open file and read content # Open file and read content
try: try:
@ -30,11 +31,11 @@ def read_file(file_path):
file_content = f.read() file_content = f.read()
except IOError as e: except IOError as e:
raise MoulinetteError(errno.EACCES, raise MoulinetteError(errno.EACCES,
m18n.g('cannot_open_file', moulinette.m18n.g('cannot_open_file',
file=file_path, error=str(e))) file=file_path, error=str(e)))
except Exception as e: except Exception as e:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
m18n.g('error_reading_file', moulinette.m18n.g('error_reading_file',
file=file_path, error=str(e))) file=file_path, error=str(e)))
return file_content return file_content
@ -56,7 +57,7 @@ def read_json(file_path):
loaded_json = json.loads(file_content) loaded_json = json.loads(file_content)
except ValueError as e: except ValueError as e:
raise MoulinetteError(errno.EINVAL, raise MoulinetteError(errno.EINVAL,
m18n.g('corrupted_json', moulinette.m18n.g('corrupted_json',
ressource=file_path, error=str(e))) ressource=file_path, error=str(e)))
return loaded_json return loaded_json
@ -88,11 +89,11 @@ def write_to_file(file_path, data, file_mode="w"):
f.write(data) f.write(data)
except IOError as e: except IOError as e:
raise MoulinetteError(errno.EACCES, raise MoulinetteError(errno.EACCES,
m18n.g('cannot_write_file', moulinette.m18n.g('cannot_write_file',
file=file_path, error=str(e))) file=file_path, error=str(e)))
except Exception as e: except Exception as e:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
m18n.g('error_writing_file', moulinette.m18n.g('error_writing_file',
file=file_path, error=str(e))) file=file_path, error=str(e)))
@ -129,11 +130,11 @@ def write_to_json(file_path, data):
json.dump(data, f) json.dump(data, f)
except IOError as e: except IOError as e:
raise MoulinetteError(errno.EACCES, raise MoulinetteError(errno.EACCES,
m18n.g('cannot_write_file', moulinette.m18n.g('cannot_write_file',
file=file_path, error=str(e))) file=file_path, error=str(e)))
except Exception as e: except Exception as e:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
m18n.g('_error_writing_file', moulinette.m18n.g('_error_writing_file',
file=file_path, error=str(e))) file=file_path, error=str(e)))
@ -154,7 +155,7 @@ def mkdir(path, mode=0777, parents=False, uid=None, gid=None, force=False):
""" """
if os.path.exists(path) and not force: if os.path.exists(path) and not force:
raise OSError(errno.EEXIST, m18n.g('folder_exists', path=path)) raise OSError(errno.EEXIST, moulinette.m18n.g('folder_exists', path=path))
if parents: if parents:
# Create parents directories as needed # Create parents directories as needed
@ -194,7 +195,7 @@ def chown(path, uid=None, gid=None, recursive=False):
uid = getpwnam(uid).pw_uid uid = getpwnam(uid).pw_uid
except KeyError: except KeyError:
raise MoulinetteError(errno.EINVAL, raise MoulinetteError(errno.EINVAL,
m18n.g('unknown_user', user=uid)) moulinette.m18n.g('unknown_user', user=uid))
elif uid is None: elif uid is None:
uid = -1 uid = -1
if isinstance(gid, basestring): if isinstance(gid, basestring):
@ -202,7 +203,7 @@ def chown(path, uid=None, gid=None, recursive=False):
gid = grp.getgrnam(gid).gr_gid gid = grp.getgrnam(gid).gr_gid
except KeyError: except KeyError:
raise MoulinetteError(errno.EINVAL, raise MoulinetteError(errno.EINVAL,
m18n.g('unknown_group', group=gid)) moulinette.m18n.g('unknown_group', group=gid))
elif gid is None: elif gid is None:
gid = -1 gid = -1
@ -216,7 +217,7 @@ def chown(path, uid=None, gid=None, recursive=False):
os.chown(os.path.join(root, f), uid, gid) os.chown(os.path.join(root, f), uid, gid)
except Exception as e: except Exception as e:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
m18n.g('error_changing_file_permissions', moulinette.m18n.g('error_changing_file_permissions',
path=path, error=str(e))) path=path, error=str(e)))
@ -242,7 +243,7 @@ def chmod(path, mode, fmode=None, recursive=False):
os.chmod(os.path.join(root, f), fmode) os.chmod(os.path.join(root, f), fmode)
except Exception as e: except Exception as e:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
m18n.g('error_changing_file_permissions', moulinette.m18n.g('error_changing_file_permissions',
path=path, error=str(e))) path=path, error=str(e)))
@ -263,5 +264,5 @@ def rm(path, recursive=False, force=False):
except OSError as e: except OSError as e:
if not force: if not force:
raise MoulinetteError(errno.EIO, raise MoulinetteError(errno.EIO,
m18n.g('error_removing', moulinette.m18n.g('error_removing',
path=path, error=str(e))) path=path, error=str(e)))

View file

@ -2,6 +2,7 @@ import errno
import requests import requests
import json import json
import moulinette
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
@ -23,24 +24,24 @@ def download_text(url, timeout=30):
# Invalid URL # Invalid URL
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
raise MoulinetteError(errno.EBADE, raise MoulinetteError(errno.EBADE,
m18n.g('invalid_url', url=url)) moulinette.m18n.g('invalid_url', url=url))
# SSL exceptions # SSL exceptions
except requests.exceptions.SSLError: except requests.exceptions.SSLError:
raise MoulinetteError(errno.EBADE, raise MoulinetteError(errno.EBADE,
m18n.g('download_ssl_error', url=url)) moulinette.m18n.g('download_ssl_error', url=url))
# Timeout exceptions # Timeout exceptions
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
raise MoulinetteError(errno.ETIME, raise MoulinetteError(errno.ETIME,
m18n.g('download_timeout', url=url)) moulinette.m18n.g('download_timeout', url=url))
# Unknown stuff # Unknown stuff
except Exception as e: except Exception as e:
raise MoulinetteError(errno.ECONNRESET, raise MoulinetteError(errno.ECONNRESET,
m18n.g('download_unknown_error', moulinette.m18n.g('download_unknown_error',
url=url, error=str(e))) url=url, error=str(e)))
# Assume error if status code is not 200 (OK) # Assume error if status code is not 200 (OK)
if r.status_code != 200: if r.status_code != 200:
raise MoulinetteError(errno.EBADE, raise MoulinetteError(errno.EBADE,
m18n.g('download_bad_status_code', moulinette.m18n.g('download_bad_status_code',
url=url, code=str(r.status_code))) url=url, code=str(r.status_code)))
return r.text return r.text
@ -56,6 +57,6 @@ def download_json(url, timeout=30):
loaded_json = json.loads(text) loaded_json = json.loads(text)
except ValueError: except ValueError:
raise MoulinetteError(errno.EINVAL, raise MoulinetteError(errno.EINVAL,
m18n.g('corrupted_json', ressource=url)) moulinette.m18n.g('corrupted_json', ressource=url))
return loaded_json return loaded_json