Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / errors.py @ 12be2bd2

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 144b3551 Stavros Sachtouris
            '  /config set cloud.default.token <t0k3n>',
85 f10cef01 Stavros Sachtouris
            'B. (advanced users) Explicitly set an %s endpoint URL' % (
86 8cec3671 Stavros Sachtouris
                service.upper()),
87 031ca67d Stavros Sachtouris
            'Note: URL option has a higher priority, so delete it to',
88 8cec3671 Stavros Sachtouris
            'make that work',
89 144b3551 Stavros Sachtouris
            '  /config delete cloud.default.url',
90 144b3551 Stavros Sachtouris
            '  /config set cloud.%s.url <%s_URL>' % (
91 362adf50 Stavros Sachtouris
                service, service.upper())]
92 8cec3671 Stavros Sachtouris
        super(CLIBaseUrlError, self).__init__(message, details, importance)
93 8cec3671 Stavros Sachtouris
94 8cec3671 Stavros Sachtouris
95 c9e706b2 Stavros Sachtouris
class CLISyntaxError(CLIError):
96 0238c167 Stavros Sachtouris
    def __init__(self, message='Syntax Error', details=[], importance=1):
97 0238c167 Stavros Sachtouris
        super(CLISyntaxError, self).__init__(message, details, importance)
98 fd5db045 Stavros Sachtouris
99 c9e706b2 Stavros Sachtouris
100 c9e706b2 Stavros Sachtouris
class CLIUnknownCommand(CLIError):
101 0238c167 Stavros Sachtouris
    def __init__(self, message='Unknown Command', details=[], importance=1):
102 0238c167 Stavros Sachtouris
        super(CLIUnknownCommand, self).__init__(message, details, importance)
103 fd5db045 Stavros Sachtouris
104 c9e706b2 Stavros Sachtouris
105 926d6863 Stavros Sachtouris
class CLICmdSpecError(CLIError):
106 de73876b Stavros Sachtouris
    def __init__(
107 24ff0a35 Stavros Sachtouris
            self, message='Command Specification Error',
108 24ff0a35 Stavros Sachtouris
            details=[], importance=0):
109 0238c167 Stavros Sachtouris
        super(CLICmdSpecError, self).__init__(message, details, importance)
110 fd5db045 Stavros Sachtouris
111 c9e706b2 Stavros Sachtouris
112 6069b53b Stavros Sachtouris
def raiseCLIError(err, message='', importance=0, details=[]):
113 83ba5545 Stavros Sachtouris
    """
114 83ba5545 Stavros Sachtouris
    :param err: (Exception) the original error message, if None, a new
115 83ba5545 Stavros Sachtouris
        CLIError is born which is conceptually bind to raiser
116 83ba5545 Stavros Sachtouris

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

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

122 83ba5545 Stavros Sachtouris
    :param details: (list) various information on the error
123 83ba5545 Stavros Sachtouris

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