Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / errors.py @ 82e32e50

History | View | Annotate | Download (20.7 kB)

1 a00de254 Stavros Sachtouris
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 a00de254 Stavros Sachtouris
#
3 a00de254 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 a00de254 Stavros Sachtouris
# without modification, are permitted provided that the following
5 a00de254 Stavros Sachtouris
# conditions are met:
6 a00de254 Stavros Sachtouris
#
7 a00de254 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 a00de254 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 a00de254 Stavros Sachtouris
#      disclaimer.
10 a00de254 Stavros Sachtouris
#
11 a00de254 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 a00de254 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 a00de254 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 a00de254 Stavros Sachtouris
#      provided with the distribution.
15 a00de254 Stavros Sachtouris
#
16 a00de254 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a00de254 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a00de254 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a00de254 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a00de254 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a00de254 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a00de254 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a00de254 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a00de254 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a00de254 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a00de254 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a00de254 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 a00de254 Stavros Sachtouris
#
29 a00de254 Stavros Sachtouris
# The views and conclusions contained in the software and
30 a00de254 Stavros Sachtouris
# documentation are those of the authors and should not be
31 a00de254 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 a00de254 Stavros Sachtouris
# or implied, of GRNET S.A.command
33 a00de254 Stavros Sachtouris
34 a00de254 Stavros Sachtouris
from traceback import print_stack, print_exc
35 a00de254 Stavros Sachtouris
36 a00de254 Stavros Sachtouris
from kamaki.clients import ClientError
37 dc6fc88e Stavros Sachtouris
from kamaki.cli.errors import CLIError, raiseCLIError, CLISyntaxError
38 a00de254 Stavros Sachtouris
from kamaki.cli import _debug, kloger
39 ca092af4 Stavros Sachtouris
from kamaki.cli.utils import format_size
40 a00de254 Stavros Sachtouris
41 a00de254 Stavros Sachtouris
42 a00de254 Stavros Sachtouris
class generic(object):
43 a00de254 Stavros Sachtouris
44 a00de254 Stavros Sachtouris
    @classmethod
45 a00de254 Stavros Sachtouris
    def all(this, foo):
46 a00de254 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
47 a00de254 Stavros Sachtouris
            try:
48 a00de254 Stavros Sachtouris
                return foo(self, *args, **kwargs)
49 a00de254 Stavros Sachtouris
            except Exception as e:
50 a00de254 Stavros Sachtouris
                if _debug:
51 a00de254 Stavros Sachtouris
                    print_stack()
52 a00de254 Stavros Sachtouris
                    print_exc(e)
53 a00de254 Stavros Sachtouris
                raiseCLIError(e)
54 a00de254 Stavros Sachtouris
        return _raise
55 a00de254 Stavros Sachtouris
56 a03ade9e Stavros Sachtouris
    @classmethod
57 f724cd35 Stavros Sachtouris
    def _connection(this, foo):
58 a03ade9e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
59 a03ade9e Stavros Sachtouris
            try:
60 a03ade9e Stavros Sachtouris
                foo(self, *args, **kwargs)
61 a03ade9e Stavros Sachtouris
            except ClientError as ce:
62 24ff0a35 Stavros Sachtouris
                ce_msg = ('%s' % ce).lower()
63 a03ade9e Stavros Sachtouris
                if ce.status == 401:
64 a03ade9e Stavros Sachtouris
                    raiseCLIError(ce, 'Authorization failed', details=[
65 a03ade9e Stavros Sachtouris
                        'Make sure a valid token is provided:',
66 4018326d Stavros Sachtouris
                        '  to check if token is valid: /user authenticate',
67 a03ade9e Stavros Sachtouris
                        '  to set token: /config set [.server.]token <token>',
68 a03ade9e Stavros Sachtouris
                        '  to get current token: /config get [server.]token'])
69 1395c40e Stavros Sachtouris
                elif ce.status in range(-12, 200) + [302, 401, 403, 500]:
70 a03ade9e Stavros Sachtouris
                    raiseCLIError(ce, importance=3, details=[
71 f724cd35 Stavros Sachtouris
                        'Check if serviceis up'])
72 24ff0a35 Stavros Sachtouris
                elif ce.status == 404 and 'kamakihttpresponse' in ce_msg:
73 5a673575 Stavros Sachtouris
                    client = getattr(self, 'client', None)
74 5a673575 Stavros Sachtouris
                    if not client:
75 5a673575 Stavros Sachtouris
                        raise
76 5a673575 Stavros Sachtouris
                    url = getattr(client, 'base_url', '<empty>')
77 de73876b Stavros Sachtouris
                    msg = 'Invalid service url %s' % url
78 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
79 f724cd35 Stavros Sachtouris
                        'Check if authentication url is correct',
80 f724cd35 Stavros Sachtouris
                        '  check current url:   /config get url',
81 f724cd35 Stavros Sachtouris
                        '  set new auth. url:   /config set url'])
82 a03ade9e Stavros Sachtouris
                raise
83 a03ade9e Stavros Sachtouris
        return _raise
84 a03ade9e Stavros Sachtouris
85 a00de254 Stavros Sachtouris
86 4018326d Stavros Sachtouris
class user(object):
87 a00de254 Stavros Sachtouris
88 a00de254 Stavros Sachtouris
    _token_details = [
89 a03ade9e Stavros Sachtouris
        'To check default token: /config get token',
90 a03ade9e Stavros Sachtouris
        'If set/update a token:',
91 f724cd35 Stavros Sachtouris
        '*  (permanent):  /config set token <token>',
92 f724cd35 Stavros Sachtouris
        '*  (temporary):  re-run with <token> parameter']
93 a00de254 Stavros Sachtouris
94 a00de254 Stavros Sachtouris
    @classmethod
95 a03ade9e Stavros Sachtouris
    def load(this, foo):
96 a00de254 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
97 a00de254 Stavros Sachtouris
            r = foo(self, *args, **kwargs)
98 a00de254 Stavros Sachtouris
            try:
99 a00de254 Stavros Sachtouris
                client = getattr(self, 'client')
100 a00de254 Stavros Sachtouris
            except AttributeError as ae:
101 a00de254 Stavros Sachtouris
                raiseCLIError(ae, 'Client setup failure', importance=3)
102 a00de254 Stavros Sachtouris
            if not getattr(client, 'token', False):
103 a00de254 Stavros Sachtouris
                kloger.warning(
104 a00de254 Stavros Sachtouris
                    'No permanent token (try: kamaki config set token <tkn>)')
105 a00de254 Stavros Sachtouris
            if not getattr(client, 'base_url', False):
106 f724cd35 Stavros Sachtouris
                msg = 'Missing synnefo URL'
107 de73876b Stavros Sachtouris
                raise CLIError(msg, importance=3, details=[
108 f724cd35 Stavros Sachtouris
                    'Check if authentication url is correct',
109 f724cd35 Stavros Sachtouris
                        '  check current url:  /config get url',
110 f724cd35 Stavros Sachtouris
                        '  set new auth. url:  /config set url'])
111 a00de254 Stavros Sachtouris
            return r
112 a00de254 Stavros Sachtouris
        return _raise
113 a00de254 Stavros Sachtouris
114 a00de254 Stavros Sachtouris
    @classmethod
115 a00de254 Stavros Sachtouris
    def authenticate(this, foo):
116 a00de254 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
117 a00de254 Stavros Sachtouris
            try:
118 9bc8317f Stavros Sachtouris
                return foo(self, *args, **kwargs)
119 a00de254 Stavros Sachtouris
            except ClientError as ce:
120 a00de254 Stavros Sachtouris
                if ce.status == 401:
121 a00de254 Stavros Sachtouris
                    token = kwargs.get('custom_token', 0) or self.client.token
122 de73876b Stavros Sachtouris
                    msg = (
123 de73876b Stavros Sachtouris
                        'Authorization failed for token %s' % token
124 de73876b Stavros Sachtouris
                    ) if token else 'No token provided',
125 de73876b Stavros Sachtouris
                    details = [] if token else this._token_details
126 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=details)
127 82e32e50 Stavros Sachtouris
                raise ce
128 436bd910 Stavros Sachtouris
            self._raise = foo
129 a00de254 Stavros Sachtouris
        return _raise
130 dc6fc88e Stavros Sachtouris
131 dc6fc88e Stavros Sachtouris
132 dc6fc88e Stavros Sachtouris
class history(object):
133 dc6fc88e Stavros Sachtouris
    @classmethod
134 dc6fc88e Stavros Sachtouris
    def init(this, foo):
135 dc6fc88e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
136 dc6fc88e Stavros Sachtouris
            r = foo(self, *args, **kwargs)
137 dc6fc88e Stavros Sachtouris
            if not hasattr(self, 'history'):
138 dc6fc88e Stavros Sachtouris
                raise CLIError('Failed to load history', importance=2)
139 dc6fc88e Stavros Sachtouris
            return r
140 dc6fc88e Stavros Sachtouris
        return _raise
141 dc6fc88e Stavros Sachtouris
142 dc6fc88e Stavros Sachtouris
    @classmethod
143 dc6fc88e Stavros Sachtouris
    def _get_cmd_ids(this, foo):
144 dc6fc88e Stavros Sachtouris
        def _raise(self, cmd_ids, *args, **kwargs):
145 dc6fc88e Stavros Sachtouris
            if not cmd_ids:
146 de73876b Stavros Sachtouris
                raise CLISyntaxError(
147 de73876b Stavros Sachtouris
                    'Usage: <id1|id1-id2> [id3|id3-id4] ...',
148 dc6fc88e Stavros Sachtouris
                    details=self.__doc__.split('\n'))
149 dc6fc88e Stavros Sachtouris
            return foo(self, cmd_ids, *args, **kwargs)
150 dc6fc88e Stavros Sachtouris
        return _raise
151 dc6fc88e Stavros Sachtouris
152 a03ade9e Stavros Sachtouris
153 a03ade9e Stavros Sachtouris
class cyclades(object):
154 b04288f7 Stavros Sachtouris
    about_flavor_id = [
155 b04288f7 Stavros Sachtouris
        'How to pick a valid flavor id:',
156 b04288f7 Stavros Sachtouris
        '* get a list of flavor ids: /flavor list',
157 b04288f7 Stavros Sachtouris
        '* details of flavor: /flavor info <flavor id>']
158 b04288f7 Stavros Sachtouris
159 5a673575 Stavros Sachtouris
    about_network_id = [
160 5a673575 Stavros Sachtouris
        'How to pick a valid network id:',
161 5a673575 Stavros Sachtouris
        '* get a list of network ids: /network list',
162 5a673575 Stavros Sachtouris
        '* details of network: /network info <network id>']
163 5a673575 Stavros Sachtouris
164 a03ade9e Stavros Sachtouris
    @classmethod
165 a03ade9e Stavros Sachtouris
    def connection(this, foo):
166 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
167 a03ade9e Stavros Sachtouris
168 b04288f7 Stavros Sachtouris
    @classmethod
169 b04288f7 Stavros Sachtouris
    def date(this, foo):
170 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
171 b04288f7 Stavros Sachtouris
            try:
172 b04288f7 Stavros Sachtouris
                return foo(self, *args, **kwargs)
173 b04288f7 Stavros Sachtouris
            except ClientError as ce:
174 b04288f7 Stavros Sachtouris
                if ce.status == 400 and 'changes-since' in ('%s' % ce):
175 b04288f7 Stavros Sachtouris
                    raise CLIError(
176 b04288f7 Stavros Sachtouris
                        'Incorrect date format for --since',
177 b04288f7 Stavros Sachtouris
                        details=['Accepted date format: d/m/y'])
178 b04288f7 Stavros Sachtouris
                raise
179 b04288f7 Stavros Sachtouris
        return _raise
180 b04288f7 Stavros Sachtouris
181 b04288f7 Stavros Sachtouris
    @classmethod
182 5a673575 Stavros Sachtouris
    def network_id(this, foo):
183 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
184 5a673575 Stavros Sachtouris
            network_id = kwargs.get('network_id', None)
185 5a673575 Stavros Sachtouris
            try:
186 5a673575 Stavros Sachtouris
                network_id = int(network_id)
187 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
188 5a673575 Stavros Sachtouris
            except ValueError as ve:
189 de73876b Stavros Sachtouris
                msg = 'Invalid network id %s ' % network_id
190 de73876b Stavros Sachtouris
                details = ['network id must be a positive integer']
191 de73876b Stavros Sachtouris
                raiseCLIError(ve, msg, details=details, importance=1)
192 5a673575 Stavros Sachtouris
            except ClientError as ce:
193 de73876b Stavros Sachtouris
                if network_id and ce.status == 404 and (
194 de73876b Stavros Sachtouris
                    'network' in ('%s' % ce).lower()
195 de73876b Stavros Sachtouris
                ):
196 de73876b Stavros Sachtouris
                    msg = 'No network with id %s found' % network_id,
197 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=this.about_network_id)
198 5a673575 Stavros Sachtouris
                raise
199 5a673575 Stavros Sachtouris
        return _raise
200 5a673575 Stavros Sachtouris
201 5a673575 Stavros Sachtouris
    @classmethod
202 5a673575 Stavros Sachtouris
    def network_max(this, foo):
203 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
204 5a673575 Stavros Sachtouris
            try:
205 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
206 5a673575 Stavros Sachtouris
            except ClientError as ce:
207 5a673575 Stavros Sachtouris
                if ce.status == 413:
208 de73876b Stavros Sachtouris
                    msg = 'Cannot create another network',
209 24ff0a35 Stavros Sachtouris
                    details = [
210 24ff0a35 Stavros Sachtouris
                        'Maximum number of networks reached',
211 de73876b Stavros Sachtouris
                        '* to get a list of networks: /network list',
212 de73876b Stavros Sachtouris
                        '* to delete a network: /network delete <net id>']
213 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=details)
214 5a673575 Stavros Sachtouris
                raise
215 5a673575 Stavros Sachtouris
        return _raise
216 5a673575 Stavros Sachtouris
217 5a673575 Stavros Sachtouris
    @classmethod
218 5a673575 Stavros Sachtouris
    def network_in_use(this, foo):
219 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
220 5a673575 Stavros Sachtouris
            network_id = kwargs.get('network_id', None)
221 5a673575 Stavros Sachtouris
            try:
222 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
223 5a673575 Stavros Sachtouris
            except ClientError as ce:
224 d1f78278 Stavros Sachtouris
                if network_id and ce.status == 400:
225 de73876b Stavros Sachtouris
                    msg = 'Network with id %s does not exist' % network_id,
226 08aad6db Stavros Sachtouris
                    raiseCLIError(ce, msg, details=this.about_network_id)
227 d1f78278 Stavros Sachtouris
                elif network_id or ce.status == 421:
228 de73876b Stavros Sachtouris
                    msg = 'Network with id %s is in use' % network_id,
229 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
230 de73876b Stavros Sachtouris
                        'Disconnect all nics/VMs of this network first',
231 de73876b Stavros Sachtouris
                        '* to get nics: /network info %s' % network_id,
232 de73876b Stavros Sachtouris
                        '.  (under "attachments" section)',
233 de73876b Stavros Sachtouris
                        '* to disconnect: /network disconnect <nic id>'])
234 5a673575 Stavros Sachtouris
                raise
235 5a673575 Stavros Sachtouris
        return _raise
236 5a673575 Stavros Sachtouris
237 5a673575 Stavros Sachtouris
    @classmethod
238 b04288f7 Stavros Sachtouris
    def flavor_id(this, foo):
239 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
240 b04288f7 Stavros Sachtouris
            flavor_id = kwargs.get('flavor_id', None)
241 b04288f7 Stavros Sachtouris
            try:
242 b04288f7 Stavros Sachtouris
                flavor_id = int(flavor_id)
243 b04288f7 Stavros Sachtouris
                return foo(self, *args, **kwargs)
244 b04288f7 Stavros Sachtouris
            except ValueError as ve:
245 de73876b Stavros Sachtouris
                msg = 'Invalid flavor id %s ' % flavor_id,
246 de73876b Stavros Sachtouris
                details = 'Flavor id must be a positive integer',
247 de73876b Stavros Sachtouris
                raiseCLIError(ve, msg, details=details, importance=1)
248 b04288f7 Stavros Sachtouris
            except ClientError as ce:
249 de73876b Stavros Sachtouris
                if flavor_id and ce.status == 404 and (
250 de73876b Stavros Sachtouris
                    'flavor' in ('%s' % ce).lower()
251 de73876b Stavros Sachtouris
                ):
252 de73876b Stavros Sachtouris
                        msg = 'No flavor with id %s found' % flavor_id,
253 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.about_flavor_id)
254 b04288f7 Stavros Sachtouris
                raise
255 b04288f7 Stavros Sachtouris
        return _raise
256 b04288f7 Stavros Sachtouris
257 b04288f7 Stavros Sachtouris
    @classmethod
258 5a673575 Stavros Sachtouris
    def server_id(this, foo):
259 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
260 b04288f7 Stavros Sachtouris
            server_id = kwargs.get('server_id', None)
261 b04288f7 Stavros Sachtouris
            try:
262 b04288f7 Stavros Sachtouris
                server_id = int(server_id)
263 b04288f7 Stavros Sachtouris
                return foo(self, *args, **kwargs)
264 b04288f7 Stavros Sachtouris
            except ValueError as ve:
265 de73876b Stavros Sachtouris
                msg = 'Invalid server(VM) id %s' % server_id,
266 de73876b Stavros Sachtouris
                details = ['id must be a positive integer'],
267 de73876b Stavros Sachtouris
                raiseCLIError(ve, msg, details=details, importance=1)
268 b04288f7 Stavros Sachtouris
            except ClientError as ce:
269 5a673575 Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
270 de73876b Stavros Sachtouris
                if (
271 de73876b Stavros Sachtouris
                    ce.status == 404 and 'server' in err_msg
272 de73876b Stavros Sachtouris
                ) or (
273 de73876b Stavros Sachtouris
                    ce.status == 400 and 'not found' in err_msg
274 de73876b Stavros Sachtouris
                ):
275 de73876b Stavros Sachtouris
                    msg = 'server(VM) with id %s not found' % server_id,
276 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
277 de73876b Stavros Sachtouris
                        '* to get existing VM ids: /server list',
278 de73876b Stavros Sachtouris
                        '* to get VM details: /server info <VM id>'])
279 5a673575 Stavros Sachtouris
                raise
280 5a673575 Stavros Sachtouris
        return _raise
281 5a673575 Stavros Sachtouris
282 5a673575 Stavros Sachtouris
    @classmethod
283 5a673575 Stavros Sachtouris
    def firewall(this, foo):
284 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
285 5a673575 Stavros Sachtouris
            profile = kwargs.get('profile', None)
286 5a673575 Stavros Sachtouris
            try:
287 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
288 5a673575 Stavros Sachtouris
            except ClientError as ce:
289 de73876b Stavros Sachtouris
                if ce.status == 400 and profile and (
290 de73876b Stavros Sachtouris
                    'firewall' in ('%s' % ce).lower()
291 de73876b Stavros Sachtouris
                ):
292 de73876b Stavros Sachtouris
                    msg = '%s is an invalid firewall profile term' % profile
293 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
294 de73876b Stavros Sachtouris
                        'Try one of the following:',
295 de73876b Stavros Sachtouris
                        '* DISABLED: Shutdown firewall',
296 de73876b Stavros Sachtouris
                        '* ENABLED: Firewall in normal mode',
297 de73876b Stavros Sachtouris
                        '* PROTECTED: Firewall in secure mode'])
298 5a673575 Stavros Sachtouris
                raise
299 5a673575 Stavros Sachtouris
        return _raise
300 5a673575 Stavros Sachtouris
301 5a673575 Stavros Sachtouris
    @classmethod
302 5a673575 Stavros Sachtouris
    def nic_id(this, foo):
303 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
304 5a673575 Stavros Sachtouris
            try:
305 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
306 5a673575 Stavros Sachtouris
            except ClientError as ce:
307 5a673575 Stavros Sachtouris
                nic_id = kwargs.get('nic_id', None)
308 de73876b Stavros Sachtouris
                if nic_id and ce.status == 404 and (
309 de73876b Stavros Sachtouris
                    'network interface' in ('%s' % ce).lower()
310 de73876b Stavros Sachtouris
                ):
311 5a673575 Stavros Sachtouris
                    server_id = kwargs.get('server_id', '<no server>')
312 5a673575 Stavros Sachtouris
                    err_msg = 'No nic %s on server(VM) with id %s' % (
313 5a673575 Stavros Sachtouris
                        nic_id,
314 5a673575 Stavros Sachtouris
                        server_id)
315 5a673575 Stavros Sachtouris
                    raiseCLIError(ce, err_msg, details=[
316 5a673575 Stavros Sachtouris
                        '* check server(VM) with id %s: /server info %s' % (
317 5a673575 Stavros Sachtouris
                            server_id,
318 5a673575 Stavros Sachtouris
                            server_id),
319 5a673575 Stavros Sachtouris
                        '* list nics for server(VM) with id %s:' % server_id,
320 5a673575 Stavros Sachtouris
                        '      /server addr %s' % server_id])
321 5a673575 Stavros Sachtouris
                raise
322 5a673575 Stavros Sachtouris
        return _raise
323 5a673575 Stavros Sachtouris
324 5a673575 Stavros Sachtouris
    @classmethod
325 5a673575 Stavros Sachtouris
    def nic_format(this, foo):
326 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
327 5a673575 Stavros Sachtouris
            try:
328 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
329 5a673575 Stavros Sachtouris
            except IndexError as ie:
330 5a673575 Stavros Sachtouris
                nic_id = kwargs.get('nic_id', None)
331 de73876b Stavros Sachtouris
                msg = 'Invalid format for network interface (nic) %s' % nic_id
332 de73876b Stavros Sachtouris
                raiseCLIError(ie, msg, importance=1, details=[
333 de73876b Stavros Sachtouris
                    'nid_id format: nic-<server id>-<nic id>',
334 de73876b Stavros Sachtouris
                    '* get nics of a network: /network info <net id>',
335 de73876b Stavros Sachtouris
                    '    (listed the "attachments" section)'])
336 5a673575 Stavros Sachtouris
        return _raise
337 5a673575 Stavros Sachtouris
338 5a673575 Stavros Sachtouris
    @classmethod
339 5a673575 Stavros Sachtouris
    def metadata(this, foo):
340 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
341 5a673575 Stavros Sachtouris
            key = kwargs.get('key', None)
342 5a673575 Stavros Sachtouris
            try:
343 5a673575 Stavros Sachtouris
                foo(self, *args, **kwargs)
344 5a673575 Stavros Sachtouris
            except ClientError as ce:
345 de73876b Stavros Sachtouris
                if key and ce.status == 404 and (
346 de73876b Stavros Sachtouris
                    'metadata' in ('%s' % ce).lower()
347 de73876b Stavros Sachtouris
                ):
348 5a673575 Stavros Sachtouris
                        raiseCLIError(ce, 'No VM metadata with key %s' % key)
349 b04288f7 Stavros Sachtouris
                raise
350 b04288f7 Stavros Sachtouris
        return _raise
351 b04288f7 Stavros Sachtouris
352 a03ade9e Stavros Sachtouris
353 a03ade9e Stavros Sachtouris
class plankton(object):
354 a03ade9e Stavros Sachtouris
355 de73876b Stavros Sachtouris
    about_image_id = [
356 de73876b Stavros Sachtouris
        'How to pick a suitable image:',
357 b04288f7 Stavros Sachtouris
        '* get a list of image ids: /image list',
358 b04288f7 Stavros Sachtouris
        '* details of image: /flavor info <image id>']
359 a03ade9e Stavros Sachtouris
360 a03ade9e Stavros Sachtouris
    @classmethod
361 a03ade9e Stavros Sachtouris
    def connection(this, foo):
362 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
363 a03ade9e Stavros Sachtouris
364 a03ade9e Stavros Sachtouris
    @classmethod
365 a03ade9e Stavros Sachtouris
    def id(this, foo):
366 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
367 b04288f7 Stavros Sachtouris
            image_id = kwargs.get('image_id', None)
368 a03ade9e Stavros Sachtouris
            try:
369 b04288f7 Stavros Sachtouris
                foo(self, *args, **kwargs)
370 a03ade9e Stavros Sachtouris
            except ClientError as ce:
371 de73876b Stavros Sachtouris
                if image_id and (
372 de73876b Stavros Sachtouris
                    ce.status == 404
373 de73876b Stavros Sachtouris
                    or (
374 de73876b Stavros Sachtouris
                        ce.status == 400
375 de73876b Stavros Sachtouris
                        and 'image not found' in ('%s' % ce).lower())
376 de73876b Stavros Sachtouris
                    or ce.status == 411
377 de73876b Stavros Sachtouris
                ):
378 de73876b Stavros Sachtouris
                        msg = 'No image with id %s found' % image_id
379 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.about_image_id)
380 236e7d08 Stavros Sachtouris
                raise
381 236e7d08 Stavros Sachtouris
        return _raise
382 236e7d08 Stavros Sachtouris
383 236e7d08 Stavros Sachtouris
    @classmethod
384 236e7d08 Stavros Sachtouris
    def metadata(this, foo):
385 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
386 b04288f7 Stavros Sachtouris
            key = kwargs.get('key', None)
387 236e7d08 Stavros Sachtouris
            try:
388 c4aefeaf Stavros Sachtouris
                return foo(self, *args, **kwargs)
389 236e7d08 Stavros Sachtouris
            except ClientError as ce:
390 24ff0a35 Stavros Sachtouris
                ce_msg = ('%s' % ce).lower()
391 de73876b Stavros Sachtouris
                if ce.status == 404 or (
392 2005b18e Stavros Sachtouris
                        ce.status == 400 and 'metadata' in ce_msg):
393 2005b18e Stavros Sachtouris
                    msg = 'No properties with key %s in this image' % key
394 2005b18e Stavros Sachtouris
                    raiseCLIError(ce, msg)
395 a03ade9e Stavros Sachtouris
                raise
396 a03ade9e Stavros Sachtouris
        return _raise
397 1395c40e Stavros Sachtouris
398 1395c40e Stavros Sachtouris
399 1395c40e Stavros Sachtouris
class pithos(object):
400 de73876b Stavros Sachtouris
    container_howto = [
401 24ff0a35 Stavros Sachtouris
        'To specify a container:',
402 3ae60112 Stavros Sachtouris
        '  1. Set file.container variable (permanent)',
403 3ae60112 Stavros Sachtouris
        '     /config set file.container <container>',
404 de73876b Stavros Sachtouris
        '  2. --container=<container> (temporary, overrides 1)',
405 de73876b Stavros Sachtouris
        '  3. Use the container:path format (temporary, overrides all)',
406 3ae60112 Stavros Sachtouris
        'For a list of containers: /file list']
407 1395c40e Stavros Sachtouris
408 1395c40e Stavros Sachtouris
    @classmethod
409 1395c40e Stavros Sachtouris
    def connection(this, foo):
410 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
411 1395c40e Stavros Sachtouris
412 1395c40e Stavros Sachtouris
    @classmethod
413 300da0fb Stavros Sachtouris
    def account(this, foo):
414 300da0fb Stavros Sachtouris
        def _raise(self, *args, **kwargs):
415 300da0fb Stavros Sachtouris
            try:
416 300da0fb Stavros Sachtouris
                return foo(self, *args, **kwargs)
417 300da0fb Stavros Sachtouris
            except ClientError as ce:
418 300da0fb Stavros Sachtouris
                if ce.status == 403:
419 300da0fb Stavros Sachtouris
                    raiseCLIError(
420 300da0fb Stavros Sachtouris
                        ce,
421 300da0fb Stavros Sachtouris
                        'Invalid account credentials for this operation',
422 300da0fb Stavros Sachtouris
                        details=['Check user account settings'])
423 300da0fb Stavros Sachtouris
                raise
424 300da0fb Stavros Sachtouris
        return _raise
425 300da0fb Stavros Sachtouris
426 300da0fb Stavros Sachtouris
    @classmethod
427 1395c40e Stavros Sachtouris
    def quota(this, foo):
428 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
429 1395c40e Stavros Sachtouris
            try:
430 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
431 1395c40e Stavros Sachtouris
            except ClientError as ce:
432 1395c40e Stavros Sachtouris
                if ce.status == 413:
433 1395c40e Stavros Sachtouris
                    raiseCLIError(ce, 'User quota exceeded', details=[
434 1395c40e Stavros Sachtouris
                        '* get quotas:',
435 3ae60112 Stavros Sachtouris
                        '  * upper total limit:      /file quota',
436 3ae60112 Stavros Sachtouris
                        '  * container limit:  /file quota <container>',
437 1395c40e Stavros Sachtouris
                        '* set a higher quota (if permitted):',
438 3ae60112 Stavros Sachtouris
                        '    /file setquota <quota>[unit] <container>'
439 1395c40e Stavros Sachtouris
                        '    as long as <container quota> <= <total quota>'])
440 1395c40e Stavros Sachtouris
                raise
441 1395c40e Stavros Sachtouris
        return _raise
442 1395c40e Stavros Sachtouris
443 1395c40e Stavros Sachtouris
    @classmethod
444 1395c40e Stavros Sachtouris
    def container(this, foo):
445 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
446 1395c40e Stavros Sachtouris
            dst_cont = kwargs.get('dst_cont', None)
447 1395c40e Stavros Sachtouris
            try:
448 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
449 1395c40e Stavros Sachtouris
            except ClientError as ce:
450 1395c40e Stavros Sachtouris
                if ce.status == 404 and 'container' in ('%s' % ce).lower():
451 de73876b Stavros Sachtouris
                        cont = ('%s or %s' % (
452 de73876b Stavros Sachtouris
                            self.container,
453 de73876b Stavros Sachtouris
                            dst_cont)) if dst_cont else self.container
454 de73876b Stavros Sachtouris
                        msg = 'Is container %s in current account?' % (cont),
455 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.container_howto)
456 1395c40e Stavros Sachtouris
                raise
457 1395c40e Stavros Sachtouris
        return _raise
458 1395c40e Stavros Sachtouris
459 1395c40e Stavros Sachtouris
    @classmethod
460 68858765 Stavros Sachtouris
    def local_path(this, foo):
461 68858765 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
462 68858765 Stavros Sachtouris
            local_path = kwargs.get('local_path', '<None>')
463 68858765 Stavros Sachtouris
            try:
464 68858765 Stavros Sachtouris
                return foo(self, *args, **kwargs)
465 68858765 Stavros Sachtouris
            except IOError as ioe:
466 de73876b Stavros Sachtouris
                msg = 'Failed to access file %s' % local_path,
467 de73876b Stavros Sachtouris
                raiseCLIError(ioe, msg, importance=2)
468 68858765 Stavros Sachtouris
        return _raise
469 68858765 Stavros Sachtouris
470 68858765 Stavros Sachtouris
    @classmethod
471 1395c40e Stavros Sachtouris
    def object_path(this, foo):
472 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
473 1395c40e Stavros Sachtouris
            try:
474 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
475 1395c40e Stavros Sachtouris
            except ClientError as ce:
476 1395c40e Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
477 de73876b Stavros Sachtouris
                if (
478 de73876b Stavros Sachtouris
                    ce.status == 404 or ce.status == 500
479 de73876b Stavros Sachtouris
                ) and 'object' in err_msg and 'not' in err_msg:
480 de73876b Stavros Sachtouris
                    msg = 'No object %s in container %s' % (
481 de73876b Stavros Sachtouris
                        self.path,
482 de73876b Stavros Sachtouris
                        self.container)
483 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=this.container_howto)
484 1395c40e Stavros Sachtouris
                raise
485 1395c40e Stavros Sachtouris
        return _raise
486 ca092af4 Stavros Sachtouris
487 ca092af4 Stavros Sachtouris
    @classmethod
488 ca092af4 Stavros Sachtouris
    def object_size(this, foo):
489 ca092af4 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
490 ca092af4 Stavros Sachtouris
            size = kwargs.get('size', None)
491 ca092af4 Stavros Sachtouris
            start = kwargs.get('start', 0)
492 ca092af4 Stavros Sachtouris
            end = kwargs.get('end', 0)
493 ca092af4 Stavros Sachtouris
            if size:
494 ca092af4 Stavros Sachtouris
                try:
495 ca092af4 Stavros Sachtouris
                    size = int(size)
496 ca092af4 Stavros Sachtouris
                except ValueError as ve:
497 de73876b Stavros Sachtouris
                    msg = 'Invalid file size %s ' % size
498 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer']
499 de73876b Stavros Sachtouris
                    raiseCLIError(ve, msg, details=details, importance=1)
500 ca092af4 Stavros Sachtouris
            else:
501 ca092af4 Stavros Sachtouris
                try:
502 ca092af4 Stavros Sachtouris
                    start = int(start)
503 ca092af4 Stavros Sachtouris
                except ValueError as e:
504 de73876b Stavros Sachtouris
                    msg = 'Invalid start value %s in range' % start,
505 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer'],
506 de73876b Stavros Sachtouris
                    raiseCLIError(e, msg, details=details, importance=1)
507 ca092af4 Stavros Sachtouris
                try:
508 ca092af4 Stavros Sachtouris
                    end = int(end)
509 ca092af4 Stavros Sachtouris
                except ValueError as e:
510 de73876b Stavros Sachtouris
                    msg = 'Invalid end value %s in range' % end
511 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer']
512 de73876b Stavros Sachtouris
                    raiseCLIError(e, msg, details=details, importance=1)
513 ca092af4 Stavros Sachtouris
                if start > end:
514 ca092af4 Stavros Sachtouris
                    raiseCLIError(
515 ca092af4 Stavros Sachtouris
                        'Invalid range %s-%s' % (start, end),
516 ca092af4 Stavros Sachtouris
                        details=['size must be a positive integer'],
517 ca092af4 Stavros Sachtouris
                        importance=1)
518 ca092af4 Stavros Sachtouris
                size = end - start
519 ca092af4 Stavros Sachtouris
            try:
520 ca092af4 Stavros Sachtouris
                return foo(self, *args, **kwargs)
521 ca092af4 Stavros Sachtouris
            except ClientError as ce:
522 ca092af4 Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
523 24ff0a35 Stavros Sachtouris
                expected = 'object length is smaller than range length'
524 24ff0a35 Stavros Sachtouris
                if size and (
525 24ff0a35 Stavros Sachtouris
                    ce.status == 416 or (
526 24ff0a35 Stavros Sachtouris
                        ce.status == 400 and expected in err_msg)):
527 de73876b Stavros Sachtouris
                    raiseCLIError(ce, 'Remote object %s:%s <= %s %s' % (
528 24ff0a35 Stavros Sachtouris
                        self.container, self.path, format_size(size),
529 24ff0a35 Stavros Sachtouris
                        ('(%sB)' % size) if size >= 1024 else ''))
530 ca092af4 Stavros Sachtouris
                raise
531 ca092af4 Stavros Sachtouris
        return _raise