mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Merge pull request #180 from irina11y/enh-moulinette-error
[enh] Simplify moulinette errors
This commit is contained in:
commit
e6c41b100b
11 changed files with 75 additions and 148 deletions
|
@ -27,7 +27,6 @@
|
||||||
"operation_interrupted": "Operation interrupted",
|
"operation_interrupted": "Operation interrupted",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"pattern_not_match": "Does not match pattern",
|
"pattern_not_match": "Does not match pattern",
|
||||||
"permission_denied": "Permission denied",
|
|
||||||
"root_required": "You must be root to perform this action",
|
"root_required": "You must be root to perform this action",
|
||||||
"server_already_running": "A server is already running on that port",
|
"server_already_running": "A server is already running on that port",
|
||||||
"success": "Success!",
|
"success": "Success!",
|
||||||
|
|
|
@ -137,5 +137,5 @@ def cli(namespaces, args, use_cache=True, output_as=None,
|
||||||
except MoulinetteError as e:
|
except MoulinetteError as e:
|
||||||
import logging
|
import logging
|
||||||
logging.getLogger(namespaces[0]).error(e.strerror)
|
logging.getLogger(namespaces[0]).error(e.strerror)
|
||||||
return e.errno
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
import yaml
|
import yaml
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
|
@ -187,9 +186,8 @@ class PatternParameter(_ExtraParameter):
|
||||||
if msg == message:
|
if msg == message:
|
||||||
msg = m18n.g(message)
|
msg = m18n.g(message)
|
||||||
|
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError('invalid_argument',
|
||||||
m18n.g('invalid_argument',
|
argument=arg_name, error=msg)
|
||||||
argument=arg_name, error=msg))
|
|
||||||
return arg_value
|
return arg_value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -218,9 +216,8 @@ class RequiredParameter(_ExtraParameter):
|
||||||
if required and (arg_value is None or arg_value == ''):
|
if required and (arg_value is None or arg_value == ''):
|
||||||
logger.debug("argument '%s' is required",
|
logger.debug("argument '%s' is required",
|
||||||
arg_name)
|
arg_name)
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError('argument_required',
|
||||||
m18n.g('argument_required',
|
argument=arg_name)
|
||||||
argument=arg_name))
|
|
||||||
return arg_value
|
return arg_value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -285,7 +282,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('error_see_log')
|
||||||
|
|
||||||
return parameters
|
return parameters
|
||||||
|
|
||||||
|
@ -501,7 +498,7 @@ class ActionsMap(object):
|
||||||
except (AttributeError, ImportError):
|
except (AttributeError, ImportError):
|
||||||
logger.exception("unable to load function %s.%s",
|
logger.exception("unable to load function %s.%s",
|
||||||
namespace, func_name)
|
namespace, func_name)
|
||||||
raise MoulinetteError(errno.EIO, m18n.g('error_see_log'))
|
raise MoulinetteError('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):
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import errno
|
|
||||||
import gnupg
|
import gnupg
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from moulinette import m18n
|
|
||||||
from moulinette.cache import open_cachefile
|
from moulinette.cache import open_cachefile
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
|
|
||||||
|
@ -97,7 +95,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('error_see_log')
|
||||||
|
|
||||||
logger.info("session will not be stored")
|
logger.info("session will not be stored")
|
||||||
store_session = False
|
store_session = False
|
||||||
|
@ -114,7 +112,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('unable_authenticate')
|
||||||
|
|
||||||
# Store session
|
# Store session
|
||||||
if store_session:
|
if store_session:
|
||||||
|
@ -149,8 +147,7 @@ class BaseAuthenticator(object):
|
||||||
enc_pwd = f.read()
|
enc_pwd = f.read()
|
||||||
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('unable_retrieve_session')
|
||||||
m18n.g('unable_retrieve_session'))
|
|
||||||
else:
|
else:
|
||||||
gpg = gnupg.GPG()
|
gpg = gnupg.GPG()
|
||||||
gpg.encoding = 'utf-8'
|
gpg.encoding = 'utf-8'
|
||||||
|
@ -159,6 +156,5 @@ class BaseAuthenticator(object):
|
||||||
if decrypted.ok is not True:
|
if decrypted.ok is not True:
|
||||||
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('unable_retrieve_session')
|
||||||
m18n.g('unable_retrieve_session'))
|
|
||||||
return decrypted.data
|
return decrypted.data
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
# TODO: Use Python3 to remove this fix!
|
# TODO: Use Python3 to remove this fix!
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
|
@ -10,7 +9,6 @@ import crypt
|
||||||
import ldap
|
import ldap
|
||||||
import ldap.modlist as modlist
|
import ldap.modlist as modlist
|
||||||
|
|
||||||
from moulinette import m18n
|
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.authenticators import BaseAuthenticator
|
from moulinette.authenticators import BaseAuthenticator
|
||||||
|
|
||||||
|
@ -82,10 +80,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('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('ldap_server_down')
|
||||||
else:
|
else:
|
||||||
self.con = con
|
self.con = con
|
||||||
self._ensure_password_uses_strong_hash(password)
|
self._ensure_password_uses_strong_hash(password)
|
||||||
|
@ -137,7 +135,7 @@ class Authenticator(BaseAuthenticator):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("error during LDAP search operation with: base='%s', "
|
logger.exception("error during LDAP search operation with: base='%s', "
|
||||||
"filter='%s', attrs=%s and exception %s", base, filter, attrs, e)
|
"filter='%s', attrs=%s and exception %s", base, filter, attrs, e)
|
||||||
raise MoulinetteError(169, m18n.g('ldap_operation_error'))
|
raise MoulinetteError('ldap_operation_error')
|
||||||
|
|
||||||
result_list = []
|
result_list = []
|
||||||
if not attrs or 'dn' not in attrs:
|
if not attrs or 'dn' not in attrs:
|
||||||
|
@ -168,7 +166,7 @@ class Authenticator(BaseAuthenticator):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("error during LDAP add operation with: rdn='%s', "
|
logger.exception("error during LDAP add operation with: rdn='%s', "
|
||||||
"attr_dict=%s and exception %s", rdn, attr_dict, e)
|
"attr_dict=%s and exception %s", rdn, attr_dict, e)
|
||||||
raise MoulinetteError(169, m18n.g('ldap_operation_error'))
|
raise MoulinetteError('ldap_operation_error')
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -188,7 +186,7 @@ class Authenticator(BaseAuthenticator):
|
||||||
self.con.delete_s(dn)
|
self.con.delete_s(dn)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("error during LDAP delete operation with: rdn='%s' and exception %s", rdn, e)
|
logger.exception("error during LDAP delete operation with: rdn='%s' and exception %s", rdn, e)
|
||||||
raise MoulinetteError(169, m18n.g('ldap_operation_error'))
|
raise MoulinetteError('ldap_operation_error')
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -219,7 +217,7 @@ class Authenticator(BaseAuthenticator):
|
||||||
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 and exception: %s", rdn, attr_dict,
|
"attr_dict=%s, new_rdn=%s and exception: %s", rdn, attr_dict,
|
||||||
new_rdn, e)
|
new_rdn, e)
|
||||||
raise MoulinetteError(169, m18n.g('ldap_operation_error'))
|
raise MoulinetteError('ldap_operation_error')
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -238,10 +236,9 @@ class Authenticator(BaseAuthenticator):
|
||||||
if attr_found:
|
if attr_found:
|
||||||
logger.info("attribute '%s' with value '%s' is not unique",
|
logger.info("attribute '%s' with value '%s' is not unique",
|
||||||
attr_found[0], attr_found[1])
|
attr_found[0], attr_found[1])
|
||||||
raise MoulinetteError(errno.EEXIST,
|
raise MoulinetteError('ldap_attribute_already_exists',
|
||||||
m18n.g('ldap_attribute_already_exists',
|
attribute=attr_found[0],
|
||||||
attribute=attr_found[0],
|
value=attr_found[1])
|
||||||
value=attr_found[1]))
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_conflict(self, value_dict, base_dn=None):
|
def get_conflict(self, value_dict, base_dn=None):
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
|
@ -344,7 +343,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, moulinette.m18n.g('error_see_log'))
|
raise MoulinetteError('error_see_log')
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
# Retrieve interface classes
|
# Retrieve interface classes
|
||||||
|
@ -352,7 +351,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, moulinette.m18n.g('error_see_log'))
|
raise MoulinetteError('error_see_log')
|
||||||
|
|
||||||
# Instantiate or retrieve ActionsMap
|
# Instantiate or retrieve ActionsMap
|
||||||
if isinstance(actionsmap, dict):
|
if isinstance(actionsmap, dict):
|
||||||
|
@ -361,7 +360,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, moulinette.m18n.g('error_see_log'))
|
raise MoulinetteError('error_see_log')
|
||||||
|
|
||||||
return interface(amap, **kwargs)
|
return interface(amap, **kwargs)
|
||||||
|
|
||||||
|
@ -382,7 +381,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, moulinette.m18n.g('error_see_log'))
|
raise MoulinetteError('error_see_log')
|
||||||
else:
|
else:
|
||||||
return mod.Authenticator(name, **kwargs)
|
return mod.Authenticator(name, **kwargs)
|
||||||
|
|
||||||
|
@ -411,9 +410,15 @@ def clean_session(session_id, profiles=[]):
|
||||||
|
|
||||||
# Moulinette core classes ----------------------------------------------
|
# Moulinette core classes ----------------------------------------------
|
||||||
|
|
||||||
class MoulinetteError(OSError):
|
class MoulinetteError(Exception):
|
||||||
"""Moulinette base exception"""
|
"""Moulinette base exception"""
|
||||||
pass
|
def __init__(self, key, raw_msg=False, *args, **kwargs):
|
||||||
|
if raw_msg:
|
||||||
|
msg = key
|
||||||
|
else:
|
||||||
|
msg = moulinette.m18n.g(key, *args, **kwargs)
|
||||||
|
super(MoulinetteError, self).__init__(msg)
|
||||||
|
self.strerror = msg
|
||||||
|
|
||||||
|
|
||||||
class MoulinetteLock(object):
|
class MoulinetteLock(object):
|
||||||
|
@ -471,8 +476,7 @@ class MoulinetteLock(object):
|
||||||
break
|
break
|
||||||
|
|
||||||
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('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)
|
||||||
|
|
||||||
|
@ -495,10 +499,7 @@ class MoulinetteLock(object):
|
||||||
with open(self._lockfile, 'w') as f:
|
with open(self._lockfile, 'w') as f:
|
||||||
f.write(str(os.getpid()))
|
f.write(str(os.getpid()))
|
||||||
except IOError:
|
except IOError:
|
||||||
raise MoulinetteError(
|
raise MoulinetteError('root_required')
|
||||||
errno.EPERM, '%s. %s.'.format(
|
|
||||||
moulinette.m18n.g('permission_denied'),
|
|
||||||
moulinette.m18n.g('root_required')))
|
|
||||||
|
|
||||||
def _lock_PIDs(self):
|
def _lock_PIDs(self):
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
import argparse
|
import argparse
|
||||||
import copy
|
import copy
|
||||||
|
@ -142,7 +141,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('invalid_usage')
|
||||||
elif not tid:
|
elif not tid:
|
||||||
tid = GLOBAL_SECTION
|
tid = GLOBAL_SECTION
|
||||||
|
|
||||||
|
@ -158,8 +157,7 @@ class BaseActionsMapParser(object):
|
||||||
# TODO: Catch errors
|
# TODO: Catch errors
|
||||||
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('authentication_required_long')
|
||||||
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 +261,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('error_see_log')
|
||||||
|
|
||||||
# -- 'authenticator'
|
# -- 'authenticator'
|
||||||
try:
|
try:
|
||||||
|
@ -278,7 +276,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('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 +299,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('error_see_log')
|
||||||
|
|
||||||
# -- 'argument_auth'
|
# -- 'argument_auth'
|
||||||
try:
|
try:
|
||||||
|
@ -314,7 +312,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('error_see_log')
|
||||||
|
|
||||||
# -- 'lock'
|
# -- 'lock'
|
||||||
try:
|
try:
|
||||||
|
@ -327,7 +325,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('error_see_log')
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
|
@ -427,7 +425,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('error_see_log')
|
||||||
else:
|
else:
|
||||||
if value:
|
if value:
|
||||||
if self.callback_return:
|
if self.callback_return:
|
||||||
|
|
|
@ -189,7 +189,7 @@ class _HTTPArgumentParser(object):
|
||||||
|
|
||||||
def _error(self, message):
|
def _error(self, message):
|
||||||
# TODO: Raise a proper exception
|
# TODO: Raise a proper exception
|
||||||
raise MoulinetteError(1, message)
|
raise MoulinetteError(message)
|
||||||
|
|
||||||
|
|
||||||
class _ActionsMapPlugin(object):
|
class _ActionsMapPlugin(object):
|
||||||
|
@ -347,7 +347,7 @@ class _ActionsMapPlugin(object):
|
||||||
self.logout(profile)
|
self.logout(profile)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
raise error_to_response(e)
|
raise HTTPUnauthorizedResponse(e.strerror)
|
||||||
else:
|
else:
|
||||||
# Update dicts with new values
|
# Update dicts with new values
|
||||||
s_hashes[profile] = s_hash
|
s_hashes[profile] = s_hash
|
||||||
|
@ -434,7 +434,7 @@ class _ActionsMapPlugin(object):
|
||||||
try:
|
try:
|
||||||
ret = self.actionsmap.process(arguments, timeout=30, route=_route)
|
ret = self.actionsmap.process(arguments, timeout=30, route=_route)
|
||||||
except MoulinetteError as e:
|
except MoulinetteError as e:
|
||||||
raise error_to_response(e)
|
raise HTTPBadRequestResponse(e.strerror)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if isinstance(e, HTTPResponse):
|
if isinstance(e, HTTPResponse):
|
||||||
raise e
|
raise e
|
||||||
|
@ -518,38 +518,12 @@ class HTTPUnauthorizedResponse(HTTPResponse):
|
||||||
super(HTTPUnauthorizedResponse, self).__init__(output, 401)
|
super(HTTPUnauthorizedResponse, self).__init__(output, 401)
|
||||||
|
|
||||||
|
|
||||||
class HTTPForbiddenResponse(HTTPResponse):
|
|
||||||
|
|
||||||
def __init__(self, output=''):
|
|
||||||
super(HTTPForbiddenResponse, self).__init__(output, 403)
|
|
||||||
|
|
||||||
|
|
||||||
class HTTPErrorResponse(HTTPResponse):
|
class HTTPErrorResponse(HTTPResponse):
|
||||||
|
|
||||||
def __init__(self, output=''):
|
def __init__(self, output=''):
|
||||||
super(HTTPErrorResponse, self).__init__(output, 500)
|
super(HTTPErrorResponse, self).__init__(output, 500)
|
||||||
|
|
||||||
|
|
||||||
def error_to_response(error):
|
|
||||||
"""Convert a MoulinetteError to relevant HTTP response."""
|
|
||||||
if error.errno == errno.EPERM:
|
|
||||||
return HTTPForbiddenResponse(error.strerror)
|
|
||||||
elif error.errno == errno.EACCES:
|
|
||||||
return HTTPUnauthorizedResponse(error.strerror)
|
|
||||||
# Client-side error
|
|
||||||
elif error.errno in [errno.ENOENT, errno.ESRCH, errno.ENXIO, errno.EEXIST,
|
|
||||||
errno.ENODEV, errno.EINVAL, errno.ENOPKG, errno.EDESTADDRREQ]:
|
|
||||||
return HTTPBadRequestResponse(error.strerror)
|
|
||||||
# Server-side error
|
|
||||||
elif error.errno in [errno.EIO, errno.EBUSY, errno.ENODATA, errno.EINTR,
|
|
||||||
errno.ENETUNREACH]:
|
|
||||||
return HTTPErrorResponse(error.strerror)
|
|
||||||
else:
|
|
||||||
logger.debug('unknown relevant response for error [%s] %s',
|
|
||||||
error.errno, error.strerror)
|
|
||||||
return HTTPErrorResponse(error.strerror)
|
|
||||||
|
|
||||||
|
|
||||||
def format_for_response(content):
|
def format_for_response(content):
|
||||||
"""Format the resulted content of a request for the HTTP response."""
|
"""Format the resulted content of a request for the HTTP response."""
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
@ -660,7 +634,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('error_see_log')
|
||||||
ret = argparse.Namespace()
|
ret = argparse.Namespace()
|
||||||
|
|
||||||
# Perform authentication if needed
|
# Perform authentication if needed
|
||||||
|
@ -673,7 +647,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('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
|
||||||
|
@ -796,9 +770,8 @@ class Interface(BaseInterface):
|
||||||
logger.exception("unable to start the server instance on %s:%d",
|
logger.exception("unable to start the server instance on %s:%d",
|
||||||
host, port)
|
host, port)
|
||||||
if e.args[0] == errno.EADDRINUSE:
|
if e.args[0] == errno.EADDRINUSE:
|
||||||
raise MoulinetteError(errno.EADDRINUSE,
|
raise MoulinetteError('server_already_running')
|
||||||
m18n.g('server_already_running'))
|
raise MoulinetteError('error_see_log')
|
||||||
raise MoulinetteError(errno.EIO, m18n.g('error_see_log'))
|
|
||||||
|
|
||||||
# Routes handlers
|
# Routes handlers
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import errno
|
|
||||||
import getpass
|
import getpass
|
||||||
import locale
|
import locale
|
||||||
import logging
|
import logging
|
||||||
|
@ -362,7 +361,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('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)
|
||||||
|
@ -409,7 +408,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('invalid_usage')
|
||||||
|
|
||||||
# auto-complete
|
# auto-complete
|
||||||
argcomplete.autocomplete(self.actionsmap.parser._parser)
|
argcomplete.autocomplete(self.actionsmap.parser._parser)
|
||||||
|
@ -422,7 +421,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('operation_interrupted')
|
||||||
|
|
||||||
if ret is None or output_as == 'none':
|
if ret is None or output_as == 'none':
|
||||||
return
|
return
|
||||||
|
@ -472,7 +471,7 @@ class Interface(BaseInterface):
|
||||||
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(m18n.g('confirm', prompt=m)) != value:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.g('values_mismatch'))
|
raise MoulinetteError('values_mismatch')
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
|
@ -23,21 +23,16 @@ 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('file_not_exist', path=file_path)
|
||||||
m18n.g('file_not_exist', path=file_path))
|
|
||||||
|
|
||||||
# Open file and read content
|
# Open file and read content
|
||||||
try:
|
try:
|
||||||
with open(file_path, "r") as f:
|
with open(file_path, "r") as f:
|
||||||
file_content = f.read()
|
file_content = f.read()
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise MoulinetteError(errno.EACCES,
|
raise MoulinetteError('cannot_open_file', file=file_path, error=str(e))
|
||||||
m18n.g('cannot_open_file',
|
|
||||||
file=file_path, error=str(e)))
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise MoulinetteError('error_reading_file', file=file_path, error=str(e))
|
||||||
m18n.g('error_reading_file',
|
|
||||||
file=file_path, error=str(e)))
|
|
||||||
|
|
||||||
return file_content
|
return file_content
|
||||||
|
|
||||||
|
@ -57,9 +52,7 @@ def read_json(file_path):
|
||||||
try:
|
try:
|
||||||
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('corrupted_json', ressource=file_path, error=str(e))
|
||||||
m18n.g('corrupted_json',
|
|
||||||
ressource=file_path, error=str(e)))
|
|
||||||
|
|
||||||
return loaded_json
|
return loaded_json
|
||||||
|
|
||||||
|
@ -79,9 +72,7 @@ def read_yaml(file_path):
|
||||||
try:
|
try:
|
||||||
loaded_yaml = yaml.safe_load(file_content)
|
loaded_yaml = yaml.safe_load(file_content)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError('corrupted_yaml', ressource=file_path, error=str(e))
|
||||||
m18n.g('corrupted_yaml',
|
|
||||||
ressource=file_path, error=str(e)))
|
|
||||||
|
|
||||||
return loaded_yaml
|
return loaded_yaml
|
||||||
|
|
||||||
|
@ -111,13 +102,9 @@ def write_to_file(file_path, data, file_mode="w"):
|
||||||
with open(file_path, file_mode) as f:
|
with open(file_path, file_mode) as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise MoulinetteError(errno.EACCES,
|
raise MoulinetteError('cannot_write_file', file=file_path, error=str(e))
|
||||||
m18n.g('cannot_write_file',
|
|
||||||
file=file_path, error=str(e)))
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise MoulinetteError('error_writing_file', file=file_path, error=str(e))
|
||||||
m18n.g('error_writing_file',
|
|
||||||
file=file_path, error=str(e)))
|
|
||||||
|
|
||||||
|
|
||||||
def append_to_file(file_path, data):
|
def append_to_file(file_path, data):
|
||||||
|
@ -152,13 +139,9 @@ def write_to_json(file_path, data):
|
||||||
with open(file_path, "w") as f:
|
with open(file_path, "w") as f:
|
||||||
json.dump(data, f)
|
json.dump(data, f)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise MoulinetteError(errno.EACCES,
|
raise MoulinetteError('cannot_write_file', file=file_path, error=str(e))
|
||||||
m18n.g('cannot_write_file',
|
|
||||||
file=file_path, error=str(e)))
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise MoulinetteError('_error_writing_file', file=file_path, error=str(e))
|
||||||
m18n.g('_error_writing_file',
|
|
||||||
file=file_path, error=str(e)))
|
|
||||||
|
|
||||||
|
|
||||||
def mkdir(path, mode=0777, parents=False, uid=None, gid=None, force=False):
|
def mkdir(path, mode=0777, parents=False, uid=None, gid=None, force=False):
|
||||||
|
@ -223,16 +206,14 @@ def chown(path, uid=None, gid=None, recursive=False):
|
||||||
try:
|
try:
|
||||||
uid = getpwnam(uid).pw_uid
|
uid = getpwnam(uid).pw_uid
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError('unknown_user', user=uid)
|
||||||
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):
|
||||||
try:
|
try:
|
||||||
gid = grp.getgrnam(gid).gr_gid
|
gid = grp.getgrnam(gid).gr_gid
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError('unknown_group', group=gid)
|
||||||
m18n.g('unknown_group', group=gid))
|
|
||||||
elif gid is None:
|
elif gid is None:
|
||||||
gid = -1
|
gid = -1
|
||||||
|
|
||||||
|
@ -245,9 +226,7 @@ def chown(path, uid=None, gid=None, recursive=False):
|
||||||
for f in files:
|
for f in files:
|
||||||
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('error_changing_file_permissions', path=path, error=str(e))
|
||||||
m18n.g('error_changing_file_permissions',
|
|
||||||
path=path, error=str(e)))
|
|
||||||
|
|
||||||
|
|
||||||
def chmod(path, mode, fmode=None, recursive=False):
|
def chmod(path, mode, fmode=None, recursive=False):
|
||||||
|
@ -271,9 +250,7 @@ def chmod(path, mode, fmode=None, recursive=False):
|
||||||
for f in files:
|
for f in files:
|
||||||
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('error_changing_file_permissions', path=path, error=str(e))
|
||||||
m18n.g('error_changing_file_permissions',
|
|
||||||
path=path, error=str(e)))
|
|
||||||
|
|
||||||
|
|
||||||
def rm(path, recursive=False, force=False):
|
def rm(path, recursive=False, force=False):
|
||||||
|
@ -292,6 +269,4 @@ def rm(path, recursive=False, force=False):
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if not force:
|
if not force:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise MoulinetteError('error_removing', path=path, error=str(e))
|
||||||
m18n.g('error_removing',
|
|
||||||
path=path, error=str(e)))
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import errno
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from moulinette import m18n
|
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,27 +23,22 @@ def download_text(url, timeout=30, expected_status_code=200):
|
||||||
r = requests.get(url, timeout=timeout)
|
r = requests.get(url, timeout=timeout)
|
||||||
# Invalid URL
|
# Invalid URL
|
||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
raise MoulinetteError(errno.EBADE,
|
raise MoulinetteError('invalid_url', url=url)
|
||||||
m18n.g('invalid_url', url=url))
|
|
||||||
# SSL exceptions
|
# SSL exceptions
|
||||||
except requests.exceptions.SSLError:
|
except requests.exceptions.SSLError:
|
||||||
raise MoulinetteError(errno.EBADE,
|
raise MoulinetteError('download_ssl_error', url=url)
|
||||||
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('download_timeout', url=url)
|
||||||
m18n.g('download_timeout', url=url))
|
|
||||||
# Unknown stuff
|
# Unknown stuff
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.ECONNRESET,
|
raise MoulinetteError('download_unknown_error',
|
||||||
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 expected_status_code is not None \
|
if expected_status_code is not None \
|
||||||
and r.status_code != expected_status_code:
|
and r.status_code != expected_status_code:
|
||||||
raise MoulinetteError(errno.EBADE,
|
raise MoulinetteError('download_bad_status_code',
|
||||||
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
|
||||||
|
|
||||||
|
@ -66,7 +59,6 @@ def download_json(url, timeout=30, expected_status_code=200):
|
||||||
try:
|
try:
|
||||||
loaded_json = json.loads(text)
|
loaded_json = json.loads(text)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError('corrupted_json', ressource=url)
|
||||||
m18n.g('corrupted_json', ressource=url))
|
|
||||||
|
|
||||||
return loaded_json
|
return loaded_json
|
||||||
|
|
Loading…
Reference in a new issue