Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / errors.py @ f8426b5c

History | View | Annotate | Download (21.3 kB)

1 e3f01d64 Stavros Sachtouris
# Copyright 2011-2013 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 c626151a Stavros Sachtouris
CLOUDNAME = [
42 144b3551 Stavros Sachtouris
    'Note: If you use a named cloud, use its name instead of "default"']
43 c626151a Stavros Sachtouris
44 a00de254 Stavros Sachtouris
45 a00de254 Stavros Sachtouris
class generic(object):
46 a00de254 Stavros Sachtouris
47 a00de254 Stavros Sachtouris
    @classmethod
48 a00de254 Stavros Sachtouris
    def all(this, foo):
49 a00de254 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
50 a00de254 Stavros Sachtouris
            try:
51 a00de254 Stavros Sachtouris
                return foo(self, *args, **kwargs)
52 a00de254 Stavros Sachtouris
            except Exception as e:
53 a00de254 Stavros Sachtouris
                if _debug:
54 a00de254 Stavros Sachtouris
                    print_stack()
55 a00de254 Stavros Sachtouris
                    print_exc(e)
56 99085b30 Stavros Sachtouris
                if isinstance(e, CLIError) or isinstance(e, ClientError):
57 844a6bdb Stavros Sachtouris
                    raiseCLIError(e)
58 844a6bdb Stavros Sachtouris
                raiseCLIError(e, details=['%s, -d for debug info' % type(e)])
59 a00de254 Stavros Sachtouris
        return _raise
60 a00de254 Stavros Sachtouris
61 a03ade9e Stavros Sachtouris
    @classmethod
62 f724cd35 Stavros Sachtouris
    def _connection(this, foo):
63 a03ade9e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
64 a03ade9e Stavros Sachtouris
            try:
65 a03ade9e Stavros Sachtouris
                foo(self, *args, **kwargs)
66 a03ade9e Stavros Sachtouris
            except ClientError as ce:
67 24ff0a35 Stavros Sachtouris
                ce_msg = ('%s' % ce).lower()
68 a03ade9e Stavros Sachtouris
                if ce.status == 401:
69 a03ade9e Stavros Sachtouris
                    raiseCLIError(ce, 'Authorization failed', details=[
70 a03ade9e Stavros Sachtouris
                        'Make sure a valid token is provided:',
71 4018326d Stavros Sachtouris
                        '  to check if token is valid: /user authenticate',
72 c626151a Stavros Sachtouris
                        '  to set token:',
73 144b3551 Stavros Sachtouris
                        '    /config set cloud.default.token <token>',
74 c626151a Stavros Sachtouris
                        '  to get current token:',
75 144b3551 Stavros Sachtouris
                        '    /config get cloud.default.token'] + CLOUDNAME)
76 1395c40e Stavros Sachtouris
                elif ce.status in range(-12, 200) + [302, 401, 403, 500]:
77 a03ade9e Stavros Sachtouris
                    raiseCLIError(ce, importance=3, details=[
78 819311d3 Stavros Sachtouris
                        'Check if service is up'])
79 24ff0a35 Stavros Sachtouris
                elif ce.status == 404 and 'kamakihttpresponse' in ce_msg:
80 5a673575 Stavros Sachtouris
                    client = getattr(self, 'client', None)
81 5a673575 Stavros Sachtouris
                    if not client:
82 5a673575 Stavros Sachtouris
                        raise
83 5a673575 Stavros Sachtouris
                    url = getattr(client, 'base_url', '<empty>')
84 031ca67d Stavros Sachtouris
                    msg = 'Invalid service URL %s' % url
85 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
86 031ca67d Stavros Sachtouris
                        'Check if authentication URL is correct',
87 031ca67d Stavros Sachtouris
                        '  check current URL:',
88 144b3551 Stavros Sachtouris
                        '    /config get cloud.default.url',
89 031ca67d Stavros Sachtouris
                        '  set new authentication URL:',
90 144b3551 Stavros Sachtouris
                        '    /config set cloud.default.url'] + CLOUDNAME)
91 a03ade9e Stavros Sachtouris
                raise
92 a03ade9e Stavros Sachtouris
        return _raise
93 a03ade9e Stavros Sachtouris
94 a00de254 Stavros Sachtouris
95 4018326d Stavros Sachtouris
class user(object):
96 a00de254 Stavros Sachtouris
97 a00de254 Stavros Sachtouris
    _token_details = [
98 144b3551 Stavros Sachtouris
        'To check default token: /config get cloud.default.token',
99 a03ade9e Stavros Sachtouris
        'If set/update a token:',
100 144b3551 Stavros Sachtouris
        '*  (permanent):  /config set cloud.default.token <token>',
101 c626151a Stavros Sachtouris
        '*  (temporary):  re-run with <token> parameter'] + CLOUDNAME
102 a00de254 Stavros Sachtouris
103 a00de254 Stavros Sachtouris
    @classmethod
104 a03ade9e Stavros Sachtouris
    def load(this, foo):
105 a00de254 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
106 a00de254 Stavros Sachtouris
            r = foo(self, *args, **kwargs)
107 a00de254 Stavros Sachtouris
            try:
108 a00de254 Stavros Sachtouris
                client = getattr(self, 'client')
109 a00de254 Stavros Sachtouris
            except AttributeError as ae:
110 a00de254 Stavros Sachtouris
                raiseCLIError(ae, 'Client setup failure', importance=3)
111 a00de254 Stavros Sachtouris
            if not getattr(client, 'token', False):
112 a00de254 Stavros Sachtouris
                kloger.warning(
113 c626151a Stavros Sachtouris
                    'No permanent token (try:'
114 144b3551 Stavros Sachtouris
                    ' kamaki config set cloud.default.token <tkn>)')
115 a00de254 Stavros Sachtouris
            if not getattr(client, 'base_url', False):
116 c626151a Stavros Sachtouris
                msg = 'Missing synnefo authentication URL'
117 de73876b Stavros Sachtouris
                raise CLIError(msg, importance=3, details=[
118 031ca67d Stavros Sachtouris
                    'Check if authentication URL is correct',
119 031ca67d Stavros Sachtouris
                        '  check current URL:',
120 144b3551 Stavros Sachtouris
                        '    /config get cloud.default.url',
121 031ca67d Stavros Sachtouris
                        '  set new auth. URL:',
122 144b3551 Stavros Sachtouris
                        '    /config set cloud.default.url'] + CLOUDNAME)
123 a00de254 Stavros Sachtouris
            return r
124 a00de254 Stavros Sachtouris
        return _raise
125 a00de254 Stavros Sachtouris
126 a00de254 Stavros Sachtouris
    @classmethod
127 a00de254 Stavros Sachtouris
    def authenticate(this, foo):
128 a00de254 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
129 a00de254 Stavros Sachtouris
            try:
130 9bc8317f Stavros Sachtouris
                return foo(self, *args, **kwargs)
131 a00de254 Stavros Sachtouris
            except ClientError as ce:
132 a00de254 Stavros Sachtouris
                if ce.status == 401:
133 a00de254 Stavros Sachtouris
                    token = kwargs.get('custom_token', 0) or self.client.token
134 de73876b Stavros Sachtouris
                    msg = (
135 de73876b Stavros Sachtouris
                        'Authorization failed for token %s' % token
136 de73876b Stavros Sachtouris
                    ) if token else 'No token provided',
137 de73876b Stavros Sachtouris
                    details = [] if token else this._token_details
138 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=details)
139 82e32e50 Stavros Sachtouris
                raise ce
140 436bd910 Stavros Sachtouris
            self._raise = foo
141 a00de254 Stavros Sachtouris
        return _raise
142 dc6fc88e Stavros Sachtouris
143 dc6fc88e Stavros Sachtouris
144 dc6fc88e Stavros Sachtouris
class history(object):
145 dc6fc88e Stavros Sachtouris
    @classmethod
146 dc6fc88e Stavros Sachtouris
    def init(this, foo):
147 dc6fc88e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
148 dc6fc88e Stavros Sachtouris
            r = foo(self, *args, **kwargs)
149 dc6fc88e Stavros Sachtouris
            if not hasattr(self, 'history'):
150 dc6fc88e Stavros Sachtouris
                raise CLIError('Failed to load history', importance=2)
151 dc6fc88e Stavros Sachtouris
            return r
152 dc6fc88e Stavros Sachtouris
        return _raise
153 dc6fc88e Stavros Sachtouris
154 dc6fc88e Stavros Sachtouris
    @classmethod
155 dc6fc88e Stavros Sachtouris
    def _get_cmd_ids(this, foo):
156 dc6fc88e Stavros Sachtouris
        def _raise(self, cmd_ids, *args, **kwargs):
157 dc6fc88e Stavros Sachtouris
            if not cmd_ids:
158 de73876b Stavros Sachtouris
                raise CLISyntaxError(
159 de73876b Stavros Sachtouris
                    'Usage: <id1|id1-id2> [id3|id3-id4] ...',
160 dc6fc88e Stavros Sachtouris
                    details=self.__doc__.split('\n'))
161 dc6fc88e Stavros Sachtouris
            return foo(self, cmd_ids, *args, **kwargs)
162 dc6fc88e Stavros Sachtouris
        return _raise
163 dc6fc88e Stavros Sachtouris
164 a03ade9e Stavros Sachtouris
165 a03ade9e Stavros Sachtouris
class cyclades(object):
166 b04288f7 Stavros Sachtouris
    about_flavor_id = [
167 b04288f7 Stavros Sachtouris
        'How to pick a valid flavor id:',
168 b04288f7 Stavros Sachtouris
        '* get a list of flavor ids: /flavor list',
169 b04288f7 Stavros Sachtouris
        '* details of flavor: /flavor info <flavor id>']
170 b04288f7 Stavros Sachtouris
171 5a673575 Stavros Sachtouris
    about_network_id = [
172 5a673575 Stavros Sachtouris
        'How to pick a valid network id:',
173 5a673575 Stavros Sachtouris
        '* get a list of network ids: /network list',
174 5a673575 Stavros Sachtouris
        '* details of network: /network info <network id>']
175 5a673575 Stavros Sachtouris
176 a03ade9e Stavros Sachtouris
    @classmethod
177 a03ade9e Stavros Sachtouris
    def connection(this, foo):
178 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
179 a03ade9e Stavros Sachtouris
180 b04288f7 Stavros Sachtouris
    @classmethod
181 b04288f7 Stavros Sachtouris
    def date(this, foo):
182 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
183 b04288f7 Stavros Sachtouris
            try:
184 b04288f7 Stavros Sachtouris
                return foo(self, *args, **kwargs)
185 b04288f7 Stavros Sachtouris
            except ClientError as ce:
186 b04288f7 Stavros Sachtouris
                if ce.status == 400 and 'changes-since' in ('%s' % ce):
187 b04288f7 Stavros Sachtouris
                    raise CLIError(
188 b04288f7 Stavros Sachtouris
                        'Incorrect date format for --since',
189 b04288f7 Stavros Sachtouris
                        details=['Accepted date format: d/m/y'])
190 b04288f7 Stavros Sachtouris
                raise
191 b04288f7 Stavros Sachtouris
        return _raise
192 b04288f7 Stavros Sachtouris
193 b04288f7 Stavros Sachtouris
    @classmethod
194 5a673575 Stavros Sachtouris
    def network_id(this, foo):
195 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
196 5a673575 Stavros Sachtouris
            network_id = kwargs.get('network_id', None)
197 5a673575 Stavros Sachtouris
            try:
198 5a673575 Stavros Sachtouris
                network_id = int(network_id)
199 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
200 5a673575 Stavros Sachtouris
            except ValueError as ve:
201 de73876b Stavros Sachtouris
                msg = 'Invalid network id %s ' % network_id
202 de73876b Stavros Sachtouris
                details = ['network id must be a positive integer']
203 de73876b Stavros Sachtouris
                raiseCLIError(ve, msg, details=details, importance=1)
204 5a673575 Stavros Sachtouris
            except ClientError as ce:
205 de73876b Stavros Sachtouris
                if network_id and ce.status == 404 and (
206 de73876b Stavros Sachtouris
                    'network' in ('%s' % ce).lower()
207 de73876b Stavros Sachtouris
                ):
208 de73876b Stavros Sachtouris
                    msg = 'No network with id %s found' % network_id,
209 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=this.about_network_id)
210 5a673575 Stavros Sachtouris
                raise
211 5a673575 Stavros Sachtouris
        return _raise
212 5a673575 Stavros Sachtouris
213 5a673575 Stavros Sachtouris
    @classmethod
214 5a673575 Stavros Sachtouris
    def network_max(this, foo):
215 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
216 5a673575 Stavros Sachtouris
            try:
217 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
218 5a673575 Stavros Sachtouris
            except ClientError as ce:
219 5a673575 Stavros Sachtouris
                if ce.status == 413:
220 de73876b Stavros Sachtouris
                    msg = 'Cannot create another network',
221 24ff0a35 Stavros Sachtouris
                    details = [
222 24ff0a35 Stavros Sachtouris
                        'Maximum number of networks reached',
223 de73876b Stavros Sachtouris
                        '* to get a list of networks: /network list',
224 de73876b Stavros Sachtouris
                        '* to delete a network: /network delete <net id>']
225 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=details)
226 5a673575 Stavros Sachtouris
                raise
227 5a673575 Stavros Sachtouris
        return _raise
228 5a673575 Stavros Sachtouris
229 5a673575 Stavros Sachtouris
    @classmethod
230 5a673575 Stavros Sachtouris
    def network_in_use(this, foo):
231 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
232 5a673575 Stavros Sachtouris
            network_id = kwargs.get('network_id', None)
233 5a673575 Stavros Sachtouris
            try:
234 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
235 5a673575 Stavros Sachtouris
            except ClientError as ce:
236 d1f78278 Stavros Sachtouris
                if network_id and ce.status == 400:
237 de73876b Stavros Sachtouris
                    msg = 'Network with id %s does not exist' % network_id,
238 08aad6db Stavros Sachtouris
                    raiseCLIError(ce, msg, details=this.about_network_id)
239 d1f78278 Stavros Sachtouris
                elif network_id or ce.status == 421:
240 de73876b Stavros Sachtouris
                    msg = 'Network with id %s is in use' % network_id,
241 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
242 de73876b Stavros Sachtouris
                        'Disconnect all nics/VMs of this network first',
243 de73876b Stavros Sachtouris
                        '* to get nics: /network info %s' % network_id,
244 de73876b Stavros Sachtouris
                        '.  (under "attachments" section)',
245 de73876b Stavros Sachtouris
                        '* to disconnect: /network disconnect <nic id>'])
246 5a673575 Stavros Sachtouris
                raise
247 5a673575 Stavros Sachtouris
        return _raise
248 5a673575 Stavros Sachtouris
249 5a673575 Stavros Sachtouris
    @classmethod
250 b04288f7 Stavros Sachtouris
    def flavor_id(this, foo):
251 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
252 b04288f7 Stavros Sachtouris
            flavor_id = kwargs.get('flavor_id', None)
253 b04288f7 Stavros Sachtouris
            try:
254 b04288f7 Stavros Sachtouris
                flavor_id = int(flavor_id)
255 b04288f7 Stavros Sachtouris
                return foo(self, *args, **kwargs)
256 b04288f7 Stavros Sachtouris
            except ValueError as ve:
257 de73876b Stavros Sachtouris
                msg = 'Invalid flavor id %s ' % flavor_id,
258 de73876b Stavros Sachtouris
                details = 'Flavor id must be a positive integer',
259 de73876b Stavros Sachtouris
                raiseCLIError(ve, msg, details=details, importance=1)
260 b04288f7 Stavros Sachtouris
            except ClientError as ce:
261 de73876b Stavros Sachtouris
                if flavor_id and ce.status == 404 and (
262 de73876b Stavros Sachtouris
                    'flavor' in ('%s' % ce).lower()
263 de73876b Stavros Sachtouris
                ):
264 de73876b Stavros Sachtouris
                        msg = 'No flavor with id %s found' % flavor_id,
265 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.about_flavor_id)
266 b04288f7 Stavros Sachtouris
                raise
267 b04288f7 Stavros Sachtouris
        return _raise
268 b04288f7 Stavros Sachtouris
269 b04288f7 Stavros Sachtouris
    @classmethod
270 5a673575 Stavros Sachtouris
    def server_id(this, foo):
271 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
272 b04288f7 Stavros Sachtouris
            server_id = kwargs.get('server_id', None)
273 b04288f7 Stavros Sachtouris
            try:
274 b04288f7 Stavros Sachtouris
                server_id = int(server_id)
275 b04288f7 Stavros Sachtouris
                return foo(self, *args, **kwargs)
276 b04288f7 Stavros Sachtouris
            except ValueError as ve:
277 de73876b Stavros Sachtouris
                msg = 'Invalid server(VM) id %s' % server_id,
278 de73876b Stavros Sachtouris
                details = ['id must be a positive integer'],
279 de73876b Stavros Sachtouris
                raiseCLIError(ve, msg, details=details, importance=1)
280 b04288f7 Stavros Sachtouris
            except ClientError as ce:
281 5a673575 Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
282 de73876b Stavros Sachtouris
                if (
283 de73876b Stavros Sachtouris
                    ce.status == 404 and 'server' in err_msg
284 de73876b Stavros Sachtouris
                ) or (
285 de73876b Stavros Sachtouris
                    ce.status == 400 and 'not found' in err_msg
286 de73876b Stavros Sachtouris
                ):
287 de73876b Stavros Sachtouris
                    msg = 'server(VM) with id %s not found' % server_id,
288 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
289 de73876b Stavros Sachtouris
                        '* to get existing VM ids: /server list',
290 de73876b Stavros Sachtouris
                        '* to get VM details: /server info <VM id>'])
291 5a673575 Stavros Sachtouris
                raise
292 5a673575 Stavros Sachtouris
        return _raise
293 5a673575 Stavros Sachtouris
294 5a673575 Stavros Sachtouris
    @classmethod
295 5a673575 Stavros Sachtouris
    def firewall(this, foo):
296 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
297 5a673575 Stavros Sachtouris
            profile = kwargs.get('profile', None)
298 5a673575 Stavros Sachtouris
            try:
299 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
300 5a673575 Stavros Sachtouris
            except ClientError as ce:
301 de73876b Stavros Sachtouris
                if ce.status == 400 and profile and (
302 de73876b Stavros Sachtouris
                    'firewall' in ('%s' % ce).lower()
303 de73876b Stavros Sachtouris
                ):
304 de73876b Stavros Sachtouris
                    msg = '%s is an invalid firewall profile term' % profile
305 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
306 de73876b Stavros Sachtouris
                        'Try one of the following:',
307 de73876b Stavros Sachtouris
                        '* DISABLED: Shutdown firewall',
308 de73876b Stavros Sachtouris
                        '* ENABLED: Firewall in normal mode',
309 de73876b Stavros Sachtouris
                        '* PROTECTED: Firewall in secure mode'])
310 5a673575 Stavros Sachtouris
                raise
311 5a673575 Stavros Sachtouris
        return _raise
312 5a673575 Stavros Sachtouris
313 5a673575 Stavros Sachtouris
    @classmethod
314 5a673575 Stavros Sachtouris
    def nic_id(this, foo):
315 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
316 5a673575 Stavros Sachtouris
            try:
317 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
318 5a673575 Stavros Sachtouris
            except ClientError as ce:
319 5a673575 Stavros Sachtouris
                nic_id = kwargs.get('nic_id', None)
320 de73876b Stavros Sachtouris
                if nic_id and ce.status == 404 and (
321 de73876b Stavros Sachtouris
                    'network interface' in ('%s' % ce).lower()
322 de73876b Stavros Sachtouris
                ):
323 5a673575 Stavros Sachtouris
                    server_id = kwargs.get('server_id', '<no server>')
324 5a673575 Stavros Sachtouris
                    err_msg = 'No nic %s on server(VM) with id %s' % (
325 5a673575 Stavros Sachtouris
                        nic_id,
326 5a673575 Stavros Sachtouris
                        server_id)
327 5a673575 Stavros Sachtouris
                    raiseCLIError(ce, err_msg, details=[
328 5a673575 Stavros Sachtouris
                        '* check server(VM) with id %s: /server info %s' % (
329 5a673575 Stavros Sachtouris
                            server_id,
330 5a673575 Stavros Sachtouris
                            server_id),
331 5a673575 Stavros Sachtouris
                        '* list nics for server(VM) with id %s:' % server_id,
332 5a673575 Stavros Sachtouris
                        '      /server addr %s' % server_id])
333 5a673575 Stavros Sachtouris
                raise
334 5a673575 Stavros Sachtouris
        return _raise
335 5a673575 Stavros Sachtouris
336 5a673575 Stavros Sachtouris
    @classmethod
337 5a673575 Stavros Sachtouris
    def nic_format(this, foo):
338 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
339 5a673575 Stavros Sachtouris
            try:
340 5a673575 Stavros Sachtouris
                return foo(self, *args, **kwargs)
341 5a673575 Stavros Sachtouris
            except IndexError as ie:
342 5a673575 Stavros Sachtouris
                nic_id = kwargs.get('nic_id', None)
343 de73876b Stavros Sachtouris
                msg = 'Invalid format for network interface (nic) %s' % nic_id
344 de73876b Stavros Sachtouris
                raiseCLIError(ie, msg, importance=1, details=[
345 de73876b Stavros Sachtouris
                    'nid_id format: nic-<server id>-<nic id>',
346 de73876b Stavros Sachtouris
                    '* get nics of a network: /network info <net id>',
347 de73876b Stavros Sachtouris
                    '    (listed the "attachments" section)'])
348 5a673575 Stavros Sachtouris
        return _raise
349 5a673575 Stavros Sachtouris
350 5a673575 Stavros Sachtouris
    @classmethod
351 5a673575 Stavros Sachtouris
    def metadata(this, foo):
352 5a673575 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
353 5a673575 Stavros Sachtouris
            key = kwargs.get('key', None)
354 5a673575 Stavros Sachtouris
            try:
355 5a673575 Stavros Sachtouris
                foo(self, *args, **kwargs)
356 5a673575 Stavros Sachtouris
            except ClientError as ce:
357 de73876b Stavros Sachtouris
                if key and ce.status == 404 and (
358 de73876b Stavros Sachtouris
                    'metadata' in ('%s' % ce).lower()
359 de73876b Stavros Sachtouris
                ):
360 5a673575 Stavros Sachtouris
                        raiseCLIError(ce, 'No VM metadata with key %s' % key)
361 b04288f7 Stavros Sachtouris
                raise
362 b04288f7 Stavros Sachtouris
        return _raise
363 b04288f7 Stavros Sachtouris
364 a03ade9e Stavros Sachtouris
365 a03ade9e Stavros Sachtouris
class plankton(object):
366 a03ade9e Stavros Sachtouris
367 de73876b Stavros Sachtouris
    about_image_id = [
368 de73876b Stavros Sachtouris
        'How to pick a suitable image:',
369 b04288f7 Stavros Sachtouris
        '* get a list of image ids: /image list',
370 67083ca0 Stavros Sachtouris
        '* details of image: /image meta <image id>']
371 a03ade9e Stavros Sachtouris
372 a03ade9e Stavros Sachtouris
    @classmethod
373 a03ade9e Stavros Sachtouris
    def connection(this, foo):
374 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
375 a03ade9e Stavros Sachtouris
376 a03ade9e Stavros Sachtouris
    @classmethod
377 a03ade9e Stavros Sachtouris
    def id(this, foo):
378 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
379 b04288f7 Stavros Sachtouris
            image_id = kwargs.get('image_id', None)
380 a03ade9e Stavros Sachtouris
            try:
381 b04288f7 Stavros Sachtouris
                foo(self, *args, **kwargs)
382 a03ade9e Stavros Sachtouris
            except ClientError as ce:
383 de73876b Stavros Sachtouris
                if image_id and (
384 de73876b Stavros Sachtouris
                    ce.status == 404
385 de73876b Stavros Sachtouris
                    or (
386 de73876b Stavros Sachtouris
                        ce.status == 400
387 de73876b Stavros Sachtouris
                        and 'image not found' in ('%s' % ce).lower())
388 de73876b Stavros Sachtouris
                    or ce.status == 411
389 de73876b Stavros Sachtouris
                ):
390 de73876b Stavros Sachtouris
                        msg = 'No image with id %s found' % image_id
391 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.about_image_id)
392 236e7d08 Stavros Sachtouris
                raise
393 236e7d08 Stavros Sachtouris
        return _raise
394 236e7d08 Stavros Sachtouris
395 236e7d08 Stavros Sachtouris
    @classmethod
396 236e7d08 Stavros Sachtouris
    def metadata(this, foo):
397 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
398 b04288f7 Stavros Sachtouris
            key = kwargs.get('key', None)
399 236e7d08 Stavros Sachtouris
            try:
400 c4aefeaf Stavros Sachtouris
                return foo(self, *args, **kwargs)
401 236e7d08 Stavros Sachtouris
            except ClientError as ce:
402 24ff0a35 Stavros Sachtouris
                ce_msg = ('%s' % ce).lower()
403 de73876b Stavros Sachtouris
                if ce.status == 404 or (
404 2005b18e Stavros Sachtouris
                        ce.status == 400 and 'metadata' in ce_msg):
405 2005b18e Stavros Sachtouris
                    msg = 'No properties with key %s in this image' % key
406 2005b18e Stavros Sachtouris
                    raiseCLIError(ce, msg)
407 a03ade9e Stavros Sachtouris
                raise
408 a03ade9e Stavros Sachtouris
        return _raise
409 1395c40e Stavros Sachtouris
410 1395c40e Stavros Sachtouris
411 1395c40e Stavros Sachtouris
class pithos(object):
412 de73876b Stavros Sachtouris
    container_howto = [
413 24ff0a35 Stavros Sachtouris
        'To specify a container:',
414 c626151a Stavros Sachtouris
        '  1. --container=<container> (temporary, overrides all)',
415 c626151a Stavros Sachtouris
        '  2. Use the container:path format (temporary, overrides 3)',
416 c626151a Stavros Sachtouris
        '  3. Set pithos_container variable (permanent)',
417 c626151a Stavros Sachtouris
        '     /config set pithos_container <container>',
418 3ae60112 Stavros Sachtouris
        'For a list of containers: /file list']
419 1395c40e Stavros Sachtouris
420 1395c40e Stavros Sachtouris
    @classmethod
421 1395c40e Stavros Sachtouris
    def connection(this, foo):
422 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
423 1395c40e Stavros Sachtouris
424 1395c40e Stavros Sachtouris
    @classmethod
425 300da0fb Stavros Sachtouris
    def account(this, foo):
426 300da0fb Stavros Sachtouris
        def _raise(self, *args, **kwargs):
427 300da0fb Stavros Sachtouris
            try:
428 300da0fb Stavros Sachtouris
                return foo(self, *args, **kwargs)
429 300da0fb Stavros Sachtouris
            except ClientError as ce:
430 300da0fb Stavros Sachtouris
                if ce.status == 403:
431 300da0fb Stavros Sachtouris
                    raiseCLIError(
432 300da0fb Stavros Sachtouris
                        ce,
433 300da0fb Stavros Sachtouris
                        'Invalid account credentials for this operation',
434 300da0fb Stavros Sachtouris
                        details=['Check user account settings'])
435 300da0fb Stavros Sachtouris
                raise
436 300da0fb Stavros Sachtouris
        return _raise
437 300da0fb Stavros Sachtouris
438 300da0fb Stavros Sachtouris
    @classmethod
439 1395c40e Stavros Sachtouris
    def quota(this, foo):
440 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
441 1395c40e Stavros Sachtouris
            try:
442 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
443 1395c40e Stavros Sachtouris
            except ClientError as ce:
444 1395c40e Stavros Sachtouris
                if ce.status == 413:
445 1395c40e Stavros Sachtouris
                    raiseCLIError(ce, 'User quota exceeded', details=[
446 1395c40e Stavros Sachtouris
                        '* get quotas:',
447 3ae60112 Stavros Sachtouris
                        '  * upper total limit:      /file quota',
448 c626151a Stavros Sachtouris
                        '  * container limit:',
449 c626151a Stavros Sachtouris
                        '    /file containerlimit get <container>',
450 c626151a Stavros Sachtouris
                        '* set a higher container limit:',
451 c626151a Stavros Sachtouris
                        '    /file containerlimit set <limit> <container>'])
452 1395c40e Stavros Sachtouris
                raise
453 1395c40e Stavros Sachtouris
        return _raise
454 1395c40e Stavros Sachtouris
455 1395c40e Stavros Sachtouris
    @classmethod
456 1395c40e Stavros Sachtouris
    def container(this, foo):
457 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
458 1395c40e Stavros Sachtouris
            dst_cont = kwargs.get('dst_cont', None)
459 1395c40e Stavros Sachtouris
            try:
460 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
461 1395c40e Stavros Sachtouris
            except ClientError as ce:
462 1395c40e Stavros Sachtouris
                if ce.status == 404 and 'container' in ('%s' % ce).lower():
463 de73876b Stavros Sachtouris
                        cont = ('%s or %s' % (
464 de73876b Stavros Sachtouris
                            self.container,
465 de73876b Stavros Sachtouris
                            dst_cont)) if dst_cont else self.container
466 de73876b Stavros Sachtouris
                        msg = 'Is container %s in current account?' % (cont),
467 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.container_howto)
468 1395c40e Stavros Sachtouris
                raise
469 1395c40e Stavros Sachtouris
        return _raise
470 1395c40e Stavros Sachtouris
471 1395c40e Stavros Sachtouris
    @classmethod
472 68858765 Stavros Sachtouris
    def local_path(this, foo):
473 68858765 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
474 68858765 Stavros Sachtouris
            local_path = kwargs.get('local_path', '<None>')
475 68858765 Stavros Sachtouris
            try:
476 68858765 Stavros Sachtouris
                return foo(self, *args, **kwargs)
477 68858765 Stavros Sachtouris
            except IOError as ioe:
478 de73876b Stavros Sachtouris
                msg = 'Failed to access file %s' % local_path,
479 de73876b Stavros Sachtouris
                raiseCLIError(ioe, msg, importance=2)
480 68858765 Stavros Sachtouris
        return _raise
481 68858765 Stavros Sachtouris
482 68858765 Stavros Sachtouris
    @classmethod
483 1395c40e Stavros Sachtouris
    def object_path(this, foo):
484 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
485 1395c40e Stavros Sachtouris
            try:
486 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
487 1395c40e Stavros Sachtouris
            except ClientError as ce:
488 1395c40e Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
489 de73876b Stavros Sachtouris
                if (
490 de73876b Stavros Sachtouris
                    ce.status == 404 or ce.status == 500
491 de73876b Stavros Sachtouris
                ) and 'object' in err_msg and 'not' in err_msg:
492 de73876b Stavros Sachtouris
                    msg = 'No object %s in container %s' % (
493 de73876b Stavros Sachtouris
                        self.path,
494 de73876b Stavros Sachtouris
                        self.container)
495 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=this.container_howto)
496 1395c40e Stavros Sachtouris
                raise
497 1395c40e Stavros Sachtouris
        return _raise
498 ca092af4 Stavros Sachtouris
499 ca092af4 Stavros Sachtouris
    @classmethod
500 ca092af4 Stavros Sachtouris
    def object_size(this, foo):
501 ca092af4 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
502 ca092af4 Stavros Sachtouris
            size = kwargs.get('size', None)
503 ca092af4 Stavros Sachtouris
            start = kwargs.get('start', 0)
504 ca092af4 Stavros Sachtouris
            end = kwargs.get('end', 0)
505 ca092af4 Stavros Sachtouris
            if size:
506 ca092af4 Stavros Sachtouris
                try:
507 ca092af4 Stavros Sachtouris
                    size = int(size)
508 ca092af4 Stavros Sachtouris
                except ValueError as ve:
509 de73876b Stavros Sachtouris
                    msg = 'Invalid file size %s ' % size
510 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer']
511 de73876b Stavros Sachtouris
                    raiseCLIError(ve, msg, details=details, importance=1)
512 ca092af4 Stavros Sachtouris
            else:
513 ca092af4 Stavros Sachtouris
                try:
514 ca092af4 Stavros Sachtouris
                    start = int(start)
515 ca092af4 Stavros Sachtouris
                except ValueError as e:
516 de73876b Stavros Sachtouris
                    msg = 'Invalid start value %s in range' % start,
517 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer'],
518 de73876b Stavros Sachtouris
                    raiseCLIError(e, msg, details=details, importance=1)
519 ca092af4 Stavros Sachtouris
                try:
520 ca092af4 Stavros Sachtouris
                    end = int(end)
521 ca092af4 Stavros Sachtouris
                except ValueError as e:
522 de73876b Stavros Sachtouris
                    msg = 'Invalid end value %s in range' % end
523 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer']
524 de73876b Stavros Sachtouris
                    raiseCLIError(e, msg, details=details, importance=1)
525 ca092af4 Stavros Sachtouris
                if start > end:
526 ca092af4 Stavros Sachtouris
                    raiseCLIError(
527 ca092af4 Stavros Sachtouris
                        'Invalid range %s-%s' % (start, end),
528 ca092af4 Stavros Sachtouris
                        details=['size must be a positive integer'],
529 ca092af4 Stavros Sachtouris
                        importance=1)
530 ca092af4 Stavros Sachtouris
                size = end - start
531 ca092af4 Stavros Sachtouris
            try:
532 ca092af4 Stavros Sachtouris
                return foo(self, *args, **kwargs)
533 ca092af4 Stavros Sachtouris
            except ClientError as ce:
534 ca092af4 Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
535 24ff0a35 Stavros Sachtouris
                expected = 'object length is smaller than range length'
536 24ff0a35 Stavros Sachtouris
                if size and (
537 24ff0a35 Stavros Sachtouris
                    ce.status == 416 or (
538 24ff0a35 Stavros Sachtouris
                        ce.status == 400 and expected in err_msg)):
539 de73876b Stavros Sachtouris
                    raiseCLIError(ce, 'Remote object %s:%s <= %s %s' % (
540 24ff0a35 Stavros Sachtouris
                        self.container, self.path, format_size(size),
541 24ff0a35 Stavros Sachtouris
                        ('(%sB)' % size) if size >= 1024 else ''))
542 ca092af4 Stavros Sachtouris
                raise
543 ca092af4 Stavros Sachtouris
        return _raise