Merge pull request #180 from irina11y/enh-moulinette-error

[enh] Simplify moulinette errors
This commit is contained in:
Alexandre Aubin 2018-12-15 15:08:58 +01:00 committed by GitHub
commit e6c41b100b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 148 deletions

View file

@ -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!",

View file

@ -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

View file

@ -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):

View file

@ -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

View file

@ -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):

View file

@ -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):

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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)))

View file

@ -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