Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / errors.py @ df55e7aa

History | View | Annotate | Download (6 kB)

1 e3f01d64 Stavros Sachtouris
# Copyright 2013 GRNET S.A. All rights reserved.
2 c9e706b2 Stavros Sachtouris
#
3 c9e706b2 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 c9e706b2 Stavros Sachtouris
# without modification, are permitted provided that the following
5 c9e706b2 Stavros Sachtouris
# conditions are met:
6 c9e706b2 Stavros Sachtouris
#
7 c9e706b2 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 c9e706b2 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 c9e706b2 Stavros Sachtouris
#      disclaimer.
10 c9e706b2 Stavros Sachtouris
#
11 c9e706b2 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 c9e706b2 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 c9e706b2 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 c9e706b2 Stavros Sachtouris
#      provided with the distribution.
15 c9e706b2 Stavros Sachtouris
#
16 c9e706b2 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 c9e706b2 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 c9e706b2 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 c9e706b2 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 c9e706b2 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 c9e706b2 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 c9e706b2 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 c9e706b2 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 c9e706b2 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 c9e706b2 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 c9e706b2 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 c9e706b2 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 c9e706b2 Stavros Sachtouris
#
29 c9e706b2 Stavros Sachtouris
# The views and conclusions contained in the software and
30 c9e706b2 Stavros Sachtouris
# documentation are those of the authors and should not be
31 c9e706b2 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 c9e706b2 Stavros Sachtouris
# or implied, of GRNET S.A.
33 c9e706b2 Stavros Sachtouris
34 137c51f5 Stavros Sachtouris
from kamaki.cli.logger import get_logger
35 6069b53b Stavros Sachtouris
36 9986e569 Stavros Sachtouris
log = get_logger('kamaki.cli')
37 de4f08ef Stavros Sachtouris
38 fd5db045 Stavros Sachtouris
39 c9e706b2 Stavros Sachtouris
class CLIError(Exception):
40 c1558584 Stavros Sachtouris
41 0238c167 Stavros Sachtouris
    def __init__(self, message, details=[], importance=0):
42 c9e706b2 Stavros Sachtouris
        """
43 f10cef01 Stavros Sachtouris
        :param message: is the main message of the Error
44 f10cef01 Stavros Sachtouris
        :param defaults: is a list of previous errors
45 f10cef01 Stavros Sachtouris
        :param importance: of the output for the user (0, 1, 2, 3)
46 0238c167 Stavros Sachtouris
        """
47 f10cef01 Stavros Sachtouris
        message += '' if message and message.endswith('\n') else '\n'
48 0238c167 Stavros Sachtouris
        super(CLIError, self).__init__(message)
49 f10cef01 Stavros Sachtouris
        self.details = (list(details) if (
50 f10cef01 Stavros Sachtouris
            isinstance(details, list) or isinstance(details, tuple)) else [
51 f10cef01 Stavros Sachtouris
                '%s' % details]) if details else []
52 0238c167 Stavros Sachtouris
        try:
53 f10cef01 Stavros Sachtouris
            self.importance = int(importance or 0)
54 0238c167 Stavros Sachtouris
        except ValueError:
55 0238c167 Stavros Sachtouris
            self.importance = 0
56 c9e706b2 Stavros Sachtouris
57 fd5db045 Stavros Sachtouris
58 362adf50 Stavros Sachtouris
class CLIUnimplemented(CLIError):
59 362adf50 Stavros Sachtouris
    def __init__(
60 362adf50 Stavros Sachtouris
            self,
61 362adf50 Stavros Sachtouris
            message='I \'M SORRY, DAVE.\nI \'M AFRAID I CAN\'T DO THAT.',
62 362adf50 Stavros Sachtouris
            details=[
63 362adf50 Stavros Sachtouris
                '      _        |',
64 362adf50 Stavros Sachtouris
                '   _-- --_     |',
65 362adf50 Stavros Sachtouris
                '  --     --    |',
66 362adf50 Stavros Sachtouris
                ' --   .   --   |',
67 362adf50 Stavros Sachtouris
                ' -_       _-   |',
68 362adf50 Stavros Sachtouris
                '   -_   _-     |',
69 362adf50 Stavros Sachtouris
                '      -        |'],
70 362adf50 Stavros Sachtouris
            importance=3):
71 362adf50 Stavros Sachtouris
        super(CLIUnimplemented, self).__init__(message, details, importance)
72 362adf50 Stavros Sachtouris
73 362adf50 Stavros Sachtouris
74 8cec3671 Stavros Sachtouris
class CLIBaseUrlError(CLIError):
75 8cec3671 Stavros Sachtouris
    def __init__(self, message='', details=[], importance=2, service=None):
76 f10cef01 Stavros Sachtouris
        service = '%s' % (service or '')
77 031ca67d Stavros Sachtouris
        message = message or 'No URL for %s' % service.lower()
78 8cec3671 Stavros Sachtouris
        details = details or [
79 f10cef01 Stavros Sachtouris
            'Two ways to resolve this:',
80 c825ddc9 Stavros Sachtouris
            '(Use the correct cloud name, instead of "default")',
81 f10cef01 Stavros Sachtouris
            'A. (recommended) Let kamaki discover endpoint URLs for all',
82 362adf50 Stavros Sachtouris
            'services by setting a single Authentication URL and token:',
83 144b3551 Stavros Sachtouris
            '  /config set cloud.default.url <AUTH_URL>',
84 f5ea3023 Stavros Sachtouris
            '  /config set cloud.default.token <t0k3n>']
85 8cec3671 Stavros Sachtouris
        super(CLIBaseUrlError, self).__init__(message, details, importance)
86 8cec3671 Stavros Sachtouris
87 8cec3671 Stavros Sachtouris
88 c9e706b2 Stavros Sachtouris
class CLISyntaxError(CLIError):
89 0238c167 Stavros Sachtouris
    def __init__(self, message='Syntax Error', details=[], importance=1):
90 0238c167 Stavros Sachtouris
        super(CLISyntaxError, self).__init__(message, details, importance)
91 8694bdad Stavros Sachtouris
92 8694bdad Stavros Sachtouris
93 8694bdad Stavros Sachtouris
class CLIInvalidArgument(CLISyntaxError):
94 8694bdad Stavros Sachtouris
    def __init__(self, message='Invalid Argument', details=[], importance=1):
95 8694bdad Stavros Sachtouris
        super(CLIInvalidArgument, self).__init__(message, details, importance)
96 fd5db045 Stavros Sachtouris
97 c9e706b2 Stavros Sachtouris
98 c9e706b2 Stavros Sachtouris
class CLIUnknownCommand(CLIError):
99 0238c167 Stavros Sachtouris
    def __init__(self, message='Unknown Command', details=[], importance=1):
100 0238c167 Stavros Sachtouris
        super(CLIUnknownCommand, self).__init__(message, details, importance)
101 fd5db045 Stavros Sachtouris
102 c9e706b2 Stavros Sachtouris
103 926d6863 Stavros Sachtouris
class CLICmdSpecError(CLIError):
104 de73876b Stavros Sachtouris
    def __init__(
105 24ff0a35 Stavros Sachtouris
            self, message='Command Specification Error',
106 24ff0a35 Stavros Sachtouris
            details=[], importance=0):
107 0238c167 Stavros Sachtouris
        super(CLICmdSpecError, self).__init__(message, details, importance)
108 fd5db045 Stavros Sachtouris
109 c9e706b2 Stavros Sachtouris
110 6069b53b Stavros Sachtouris
def raiseCLIError(err, message='', importance=0, details=[]):
111 83ba5545 Stavros Sachtouris
    """
112 83ba5545 Stavros Sachtouris
    :param err: (Exception) the original error message, if None, a new
113 83ba5545 Stavros Sachtouris
        CLIError is born which is conceptually bind to raiser
114 83ba5545 Stavros Sachtouris

115 83ba5545 Stavros Sachtouris
    :param message: (str) a custom error message that overrides err's
116 83ba5545 Stavros Sachtouris

117 83ba5545 Stavros Sachtouris
    :param importance: (int) instruction to called application (e.g. for
118 83ba5545 Stavros Sachtouris
        coloring printed error messages)
119 83ba5545 Stavros Sachtouris

120 83ba5545 Stavros Sachtouris
    :param details: (list) various information on the error
121 83ba5545 Stavros Sachtouris

122 83ba5545 Stavros Sachtouris
    :raises CLIError: it is the purpose of this method
123 83ba5545 Stavros Sachtouris
    """
124 6069b53b Stavros Sachtouris
    from traceback import format_stack
125 c1558584 Stavros Sachtouris
126 83ba5545 Stavros Sachtouris
    stack = ['%s' % type(err)] if err else ['<kamaki.cli.errors.CLIError>']
127 3667e969 Stavros Sachtouris
    stack += format_stack()
128 83ba5545 Stavros Sachtouris
129 f10cef01 Stavros Sachtouris
    details = list(details) if (
130 f10cef01 Stavros Sachtouris
        isinstance(details, list) or isinstance(details, tuple)) else [
131 f10cef01 Stavros Sachtouris
            '%s' % details]
132 e8d3b957 Stavros Sachtouris
    err_details = getattr(err, 'details', [])
133 fa7d08b6 Stavros Sachtouris
    if isinstance(err_details, list) or isinstance(err_details, tuple):
134 e8d3b957 Stavros Sachtouris
        details += list(err_details)
135 fa7d08b6 Stavros Sachtouris
    else:
136 fa7d08b6 Stavros Sachtouris
        details.append('%s' % err_details)
137 6069b53b Stavros Sachtouris
138 f10cef01 Stavros Sachtouris
    origerr = (('%s' % err) or '%s' % type(err)) if err else stack[0]
139 f10cef01 Stavros Sachtouris
    message = '%s' % message or origerr
140 6069b53b Stavros Sachtouris
141 6069b53b Stavros Sachtouris
    try:
142 dc6fc88e Stavros Sachtouris
        status = err.status or err.errno
143 6069b53b Stavros Sachtouris
    except AttributeError:
144 f10cef01 Stavros Sachtouris
        try:
145 f10cef01 Stavros Sachtouris
            status = err.errno
146 f10cef01 Stavros Sachtouris
        except AttributeError:
147 f10cef01 Stavros Sachtouris
            status = None
148 6069b53b Stavros Sachtouris
149 3667e969 Stavros Sachtouris
    if origerr not in details + [message]:
150 3667e969 Stavros Sachtouris
        details.append(origerr)
151 6069b53b Stavros Sachtouris
152 f10cef01 Stavros Sachtouris
    message += '' if message and message.endswith('\n') else '\n'
153 6069b53b Stavros Sachtouris
    if status:
154 f10cef01 Stavros Sachtouris
        message = '(%s) %s' % (status, message)
155 0238c167 Stavros Sachtouris
        try:
156 f10cef01 Stavros Sachtouris
            status = int(status)
157 0238c167 Stavros Sachtouris
        except ValueError:
158 f10cef01 Stavros Sachtouris
            raise CLIError(message, details, importance or 0)
159 f10cef01 Stavros Sachtouris
        importance = importance or status // 100
160 c1558584 Stavros Sachtouris
    importance = getattr(err, 'importance', importance)
161 6069b53b Stavros Sachtouris
    raise CLIError(message, details, importance)