Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / errors.py @ 2005b18e

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