Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / errors.py @ 236e7d08

History | View | Annotate | Download (7 kB)

1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.command
33

    
34
from traceback import print_stack, print_exc
35
import logging
36

    
37
from kamaki.clients import ClientError
38
from kamaki.cli.errors import CLIError, raiseCLIError, CLISyntaxError
39
from kamaki.cli import _debug, kloger
40

    
41
sendlog = logging.getLogger('clients.send')
42
datasendlog = logging.getLogger('data.send')
43
recvlog = logging.getLogger('clients.recv')
44
datarecvlog = logging.getLogger('data.recv')
45

    
46

    
47
class generic(object):
48

    
49
    @classmethod
50
    def all(this, foo):
51
        def _raise(self, *args, **kwargs):
52
            try:
53
                return foo(self, *args, **kwargs)
54
            except Exception as e:
55
                if _debug:
56
                    print_stack()
57
                    print_exc(e)
58
                raiseCLIError(e)
59
        return _raise
60

    
61
    @classmethod
62
    def _connection(this, foo, base_url):
63
        def _raise(self, *args, **kwargs):
64
            try:
65
                foo(self, *args, **kwargs)
66
            except ClientError as ce:
67
                if ce.status == 401:
68
                    raiseCLIError(ce, 'Authorization failed', details=[
69
                        'Make sure a valid token is provided:',
70
                        '  to check if token is valid: /astakos authenticate',
71
                        '  to set token: /config set [.server.]token <token>',
72
                        '  to get current token: /config get [server.]token'])
73
                elif ce.status in range(-12, 200) + [403, 500]:
74
                    raiseCLIError(ce, importance=3, details=[
75
                        'Check if service is up or set to url %s' % base_url,
76
                        '  to get url: /config get %s' % base_url,
77
                        '  to set url: /config set %s <URL>' % base_url])
78
                raise
79
        return _raise
80

    
81

    
82
class astakos(object):
83

    
84
    _token_details = [
85
        'To check default token: /config get token',
86
        'If set/update a token:',
87
        '*  (permanent):    /config set token <token>',
88
        '*  (temporary):    re-run with <token> parameter']
89

    
90
    @classmethod
91
    def load(this, foo):
92
        def _raise(self, *args, **kwargs):
93
            r = foo(self, *args, **kwargs)
94
            try:
95
                client = getattr(self, 'client')
96
            except AttributeError as ae:
97
                raiseCLIError(ae, 'Client setup failure', importance=3)
98
            if not getattr(client, 'token', False):
99
                kloger.warning(
100
                    'No permanent token (try: kamaki config set token <tkn>)')
101
            if not getattr(client, 'base_url', False):
102
                raise CLIError('Missing astakos server URL',
103
                    importance=3,
104
                    details=['Check if astakos.url is set correctly',
105
                    'To get astakos url:   /config get astakos.url',
106
                    'To set astakos url:   /config set astakos.url <URL>'])
107
            return r
108
        return _raise
109

    
110
    @classmethod
111
    def authenticate(this, foo):
112
        def _raise(self, *args, **kwargs):
113
            try:
114
                r = foo(self, *args, **kwargs)
115
            except ClientError as ce:
116
                if ce.status == 401:
117
                    token = kwargs.get('custom_token', 0) or self.client.token
118
                    raiseCLIError(ce,
119
                        'Authorization failed for token %s' % token if token\
120
                            else 'No token provided',
121
                        details=[] if token else this._token_details)
122
            self._raise = foo
123
            return r
124
        return _raise
125

    
126

    
127
class history(object):
128
    @classmethod
129
    def init(this, foo):
130
        def _raise(self, *args, **kwargs):
131
            r = foo(self, *args, **kwargs)
132
            if not hasattr(self, 'history'):
133
                raise CLIError('Failed to load history', importance=2)
134
            return r
135
        return _raise
136

    
137
    @classmethod
138
    def _get_cmd_ids(this, foo):
139
        def _raise(self, cmd_ids, *args, **kwargs):
140
            if not cmd_ids:
141
                raise CLISyntaxError('Usage: <id1|id1-id2> [id3|id3-id4] ...',
142
                    details=self.__doc__.split('\n'))
143
            return foo(self, cmd_ids, *args, **kwargs)
144
        return _raise
145

    
146

    
147
class cyclades(object):
148
    @classmethod
149
    def connection(this, foo):
150
        return generic._connection(foo, 'compute.url')
151

    
152

    
153
class plankton(object):
154

    
155
    about_image_id = ['To see a list of available image ids: /image list']
156

    
157
    @classmethod
158
    def connection(this, foo):
159
        return generic._connection(foo, 'image.url')
160

    
161
    @classmethod
162
    def id(this, foo):
163
        def _raise(self, image_id, *args, **kwargs):
164
            try:
165
                foo(self, image_id, *args, **kwargs)
166
            except ClientError as ce:
167
                if image_id and (ce.status == 404 or (\
168
                    ce.status == 400 and
169
                    'image not found' in ('%s' % ce).lower())):
170
                        raiseCLIError(ce,
171
                            'No image with id %s found' % image_id,
172
                            details=this.about_image_id)
173
                raise
174
        return _raise
175

    
176
    @classmethod
177
    def metadata(this, foo):
178
        def _raise(self, image_id, key, *args, **kwargs):
179
            try:
180
                foo(self, image_id, key, *args, **kwargs)
181
            except ClientError as ce:
182
                if image_id and (ce.status == 404 or (\
183
                    ce.status == 400 and
184
                    'metadata' in ('%s' % ce).lower())):
185
                        raiseCLIError(ce,
186
                            'No properties with key %s in this image' % key)
187
                raise
188
        return _raise