Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / errors.py @ 2bd23362

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 2bd23362 Stavros Sachtouris
                        'Disconnect all nics/servers 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 2bd23362 Stavros Sachtouris
                msg = 'Invalid virtual server 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 2bd23362 Stavros Sachtouris
                    msg = 'virtual server with id %s not found' % server_id,
288 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=[
289 2bd23362 Stavros Sachtouris
                        '* to get ids of all servers: /server list',
290 2bd23362 Stavros Sachtouris
                        '* to get server details: /server info <server 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 2bd23362 Stavros Sachtouris
                    err_msg = 'No nic %s on virtual server 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 2bd23362 Stavros Sachtouris
                        '* check v. server with id %s: /server info %s' % (
329 5a673575 Stavros Sachtouris
                            server_id,
330 5a673575 Stavros Sachtouris
                            server_id),
331 2bd23362 Stavros Sachtouris
                        '* list nics for v. server 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 2bd23362 Stavros Sachtouris
                        raiseCLIError(
361 2bd23362 Stavros Sachtouris
                            ce, 'No v. server metadata with key %s' % key)
362 b04288f7 Stavros Sachtouris
                raise
363 b04288f7 Stavros Sachtouris
        return _raise
364 b04288f7 Stavros Sachtouris
365 a03ade9e Stavros Sachtouris
366 a03ade9e Stavros Sachtouris
class plankton(object):
367 a03ade9e Stavros Sachtouris
368 de73876b Stavros Sachtouris
    about_image_id = [
369 de73876b Stavros Sachtouris
        'How to pick a suitable image:',
370 b04288f7 Stavros Sachtouris
        '* get a list of image ids: /image list',
371 67083ca0 Stavros Sachtouris
        '* details of image: /image meta <image id>']
372 a03ade9e Stavros Sachtouris
373 a03ade9e Stavros Sachtouris
    @classmethod
374 a03ade9e Stavros Sachtouris
    def connection(this, foo):
375 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
376 a03ade9e Stavros Sachtouris
377 a03ade9e Stavros Sachtouris
    @classmethod
378 a03ade9e Stavros Sachtouris
    def id(this, foo):
379 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
380 b04288f7 Stavros Sachtouris
            image_id = kwargs.get('image_id', None)
381 a03ade9e Stavros Sachtouris
            try:
382 b04288f7 Stavros Sachtouris
                foo(self, *args, **kwargs)
383 a03ade9e Stavros Sachtouris
            except ClientError as ce:
384 de73876b Stavros Sachtouris
                if image_id and (
385 de73876b Stavros Sachtouris
                    ce.status == 404
386 de73876b Stavros Sachtouris
                    or (
387 de73876b Stavros Sachtouris
                        ce.status == 400
388 de73876b Stavros Sachtouris
                        and 'image not found' in ('%s' % ce).lower())
389 de73876b Stavros Sachtouris
                    or ce.status == 411
390 de73876b Stavros Sachtouris
                ):
391 de73876b Stavros Sachtouris
                        msg = 'No image with id %s found' % image_id
392 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.about_image_id)
393 236e7d08 Stavros Sachtouris
                raise
394 236e7d08 Stavros Sachtouris
        return _raise
395 236e7d08 Stavros Sachtouris
396 236e7d08 Stavros Sachtouris
    @classmethod
397 236e7d08 Stavros Sachtouris
    def metadata(this, foo):
398 b04288f7 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
399 b04288f7 Stavros Sachtouris
            key = kwargs.get('key', None)
400 236e7d08 Stavros Sachtouris
            try:
401 c4aefeaf Stavros Sachtouris
                return foo(self, *args, **kwargs)
402 236e7d08 Stavros Sachtouris
            except ClientError as ce:
403 24ff0a35 Stavros Sachtouris
                ce_msg = ('%s' % ce).lower()
404 de73876b Stavros Sachtouris
                if ce.status == 404 or (
405 2005b18e Stavros Sachtouris
                        ce.status == 400 and 'metadata' in ce_msg):
406 2005b18e Stavros Sachtouris
                    msg = 'No properties with key %s in this image' % key
407 2005b18e Stavros Sachtouris
                    raiseCLIError(ce, msg)
408 a03ade9e Stavros Sachtouris
                raise
409 a03ade9e Stavros Sachtouris
        return _raise
410 1395c40e Stavros Sachtouris
411 1395c40e Stavros Sachtouris
412 1395c40e Stavros Sachtouris
class pithos(object):
413 de73876b Stavros Sachtouris
    container_howto = [
414 24ff0a35 Stavros Sachtouris
        'To specify a container:',
415 c626151a Stavros Sachtouris
        '  1. --container=<container> (temporary, overrides all)',
416 c626151a Stavros Sachtouris
        '  2. Use the container:path format (temporary, overrides 3)',
417 c626151a Stavros Sachtouris
        '  3. Set pithos_container variable (permanent)',
418 c626151a Stavros Sachtouris
        '     /config set pithos_container <container>',
419 3ae60112 Stavros Sachtouris
        'For a list of containers: /file list']
420 1395c40e Stavros Sachtouris
421 1395c40e Stavros Sachtouris
    @classmethod
422 1395c40e Stavros Sachtouris
    def connection(this, foo):
423 f724cd35 Stavros Sachtouris
        return generic._connection(foo)
424 1395c40e Stavros Sachtouris
425 1395c40e Stavros Sachtouris
    @classmethod
426 300da0fb Stavros Sachtouris
    def account(this, foo):
427 300da0fb Stavros Sachtouris
        def _raise(self, *args, **kwargs):
428 300da0fb Stavros Sachtouris
            try:
429 300da0fb Stavros Sachtouris
                return foo(self, *args, **kwargs)
430 300da0fb Stavros Sachtouris
            except ClientError as ce:
431 300da0fb Stavros Sachtouris
                if ce.status == 403:
432 300da0fb Stavros Sachtouris
                    raiseCLIError(
433 300da0fb Stavros Sachtouris
                        ce,
434 300da0fb Stavros Sachtouris
                        'Invalid account credentials for this operation',
435 300da0fb Stavros Sachtouris
                        details=['Check user account settings'])
436 300da0fb Stavros Sachtouris
                raise
437 300da0fb Stavros Sachtouris
        return _raise
438 300da0fb Stavros Sachtouris
439 300da0fb Stavros Sachtouris
    @classmethod
440 1395c40e Stavros Sachtouris
    def quota(this, foo):
441 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
442 1395c40e Stavros Sachtouris
            try:
443 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
444 1395c40e Stavros Sachtouris
            except ClientError as ce:
445 1395c40e Stavros Sachtouris
                if ce.status == 413:
446 1395c40e Stavros Sachtouris
                    raiseCLIError(ce, 'User quota exceeded', details=[
447 1395c40e Stavros Sachtouris
                        '* get quotas:',
448 3ae60112 Stavros Sachtouris
                        '  * upper total limit:      /file quota',
449 c626151a Stavros Sachtouris
                        '  * container limit:',
450 c626151a Stavros Sachtouris
                        '    /file containerlimit get <container>',
451 c626151a Stavros Sachtouris
                        '* set a higher container limit:',
452 c626151a Stavros Sachtouris
                        '    /file containerlimit set <limit> <container>'])
453 1395c40e Stavros Sachtouris
                raise
454 1395c40e Stavros Sachtouris
        return _raise
455 1395c40e Stavros Sachtouris
456 1395c40e Stavros Sachtouris
    @classmethod
457 1395c40e Stavros Sachtouris
    def container(this, foo):
458 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
459 1395c40e Stavros Sachtouris
            dst_cont = kwargs.get('dst_cont', None)
460 1395c40e Stavros Sachtouris
            try:
461 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
462 1395c40e Stavros Sachtouris
            except ClientError as ce:
463 1395c40e Stavros Sachtouris
                if ce.status == 404 and 'container' in ('%s' % ce).lower():
464 de73876b Stavros Sachtouris
                        cont = ('%s or %s' % (
465 de73876b Stavros Sachtouris
                            self.container,
466 de73876b Stavros Sachtouris
                            dst_cont)) if dst_cont else self.container
467 de73876b Stavros Sachtouris
                        msg = 'Is container %s in current account?' % (cont),
468 de73876b Stavros Sachtouris
                        raiseCLIError(ce, msg, details=this.container_howto)
469 1395c40e Stavros Sachtouris
                raise
470 1395c40e Stavros Sachtouris
        return _raise
471 1395c40e Stavros Sachtouris
472 1395c40e Stavros Sachtouris
    @classmethod
473 68858765 Stavros Sachtouris
    def local_path(this, foo):
474 68858765 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
475 68858765 Stavros Sachtouris
            local_path = kwargs.get('local_path', '<None>')
476 68858765 Stavros Sachtouris
            try:
477 68858765 Stavros Sachtouris
                return foo(self, *args, **kwargs)
478 68858765 Stavros Sachtouris
            except IOError as ioe:
479 de73876b Stavros Sachtouris
                msg = 'Failed to access file %s' % local_path,
480 de73876b Stavros Sachtouris
                raiseCLIError(ioe, msg, importance=2)
481 68858765 Stavros Sachtouris
        return _raise
482 68858765 Stavros Sachtouris
483 68858765 Stavros Sachtouris
    @classmethod
484 1395c40e Stavros Sachtouris
    def object_path(this, foo):
485 1395c40e Stavros Sachtouris
        def _raise(self, *args, **kwargs):
486 1395c40e Stavros Sachtouris
            try:
487 1395c40e Stavros Sachtouris
                return foo(self, *args, **kwargs)
488 1395c40e Stavros Sachtouris
            except ClientError as ce:
489 1395c40e Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
490 de73876b Stavros Sachtouris
                if (
491 de73876b Stavros Sachtouris
                    ce.status == 404 or ce.status == 500
492 de73876b Stavros Sachtouris
                ) and 'object' in err_msg and 'not' in err_msg:
493 de73876b Stavros Sachtouris
                    msg = 'No object %s in container %s' % (
494 de73876b Stavros Sachtouris
                        self.path,
495 de73876b Stavros Sachtouris
                        self.container)
496 de73876b Stavros Sachtouris
                    raiseCLIError(ce, msg, details=this.container_howto)
497 1395c40e Stavros Sachtouris
                raise
498 1395c40e Stavros Sachtouris
        return _raise
499 ca092af4 Stavros Sachtouris
500 ca092af4 Stavros Sachtouris
    @classmethod
501 ca092af4 Stavros Sachtouris
    def object_size(this, foo):
502 ca092af4 Stavros Sachtouris
        def _raise(self, *args, **kwargs):
503 ca092af4 Stavros Sachtouris
            size = kwargs.get('size', None)
504 ca092af4 Stavros Sachtouris
            start = kwargs.get('start', 0)
505 ca092af4 Stavros Sachtouris
            end = kwargs.get('end', 0)
506 ca092af4 Stavros Sachtouris
            if size:
507 ca092af4 Stavros Sachtouris
                try:
508 ca092af4 Stavros Sachtouris
                    size = int(size)
509 ca092af4 Stavros Sachtouris
                except ValueError as ve:
510 de73876b Stavros Sachtouris
                    msg = 'Invalid file size %s ' % size
511 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer']
512 de73876b Stavros Sachtouris
                    raiseCLIError(ve, msg, details=details, importance=1)
513 ca092af4 Stavros Sachtouris
            else:
514 ca092af4 Stavros Sachtouris
                try:
515 ca092af4 Stavros Sachtouris
                    start = int(start)
516 ca092af4 Stavros Sachtouris
                except ValueError as e:
517 de73876b Stavros Sachtouris
                    msg = 'Invalid start value %s in range' % start,
518 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer'],
519 de73876b Stavros Sachtouris
                    raiseCLIError(e, msg, details=details, importance=1)
520 ca092af4 Stavros Sachtouris
                try:
521 ca092af4 Stavros Sachtouris
                    end = int(end)
522 ca092af4 Stavros Sachtouris
                except ValueError as e:
523 de73876b Stavros Sachtouris
                    msg = 'Invalid end value %s in range' % end
524 de73876b Stavros Sachtouris
                    details = ['size must be a positive integer']
525 de73876b Stavros Sachtouris
                    raiseCLIError(e, msg, details=details, importance=1)
526 ca092af4 Stavros Sachtouris
                if start > end:
527 ca092af4 Stavros Sachtouris
                    raiseCLIError(
528 ca092af4 Stavros Sachtouris
                        'Invalid range %s-%s' % (start, end),
529 ca092af4 Stavros Sachtouris
                        details=['size must be a positive integer'],
530 ca092af4 Stavros Sachtouris
                        importance=1)
531 ca092af4 Stavros Sachtouris
                size = end - start
532 ca092af4 Stavros Sachtouris
            try:
533 ca092af4 Stavros Sachtouris
                return foo(self, *args, **kwargs)
534 ca092af4 Stavros Sachtouris
            except ClientError as ce:
535 ca092af4 Stavros Sachtouris
                err_msg = ('%s' % ce).lower()
536 24ff0a35 Stavros Sachtouris
                expected = 'object length is smaller than range length'
537 24ff0a35 Stavros Sachtouris
                if size and (
538 24ff0a35 Stavros Sachtouris
                    ce.status == 416 or (
539 24ff0a35 Stavros Sachtouris
                        ce.status == 400 and expected in err_msg)):
540 de73876b Stavros Sachtouris
                    raiseCLIError(ce, 'Remote object %s:%s <= %s %s' % (
541 24ff0a35 Stavros Sachtouris
                        self.container, self.path, format_size(size),
542 24ff0a35 Stavros Sachtouris
                        ('(%sB)' % size) if size >= 1024 else ''))
543 ca092af4 Stavros Sachtouris
                raise
544 ca092af4 Stavros Sachtouris
        return _raise