Revision 16bcc6e8
/dev/null | ||
---|---|---|
1 |
from .api import * |
|
2 |
from .http import QuotaholderClient |
|
3 |
|
|
4 |
QH_PRACTICALLY_INFINITE = 10 ** 32 |
/dev/null | ||
---|---|---|
1 |
# Copyright 2012 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from .quotaholder import QuotaholderAPI, QH_PRACTICALLY_INFINITE |
|
35 |
from .exception import (CallError, |
|
36 |
InvalidKeyError, NoEntityError, |
|
37 |
NoQuantityError, NoCapacityError, |
|
38 |
ExportLimitError, ImportLimitError, |
|
39 |
CorruptedError, InvalidDataError, |
|
40 |
DuplicateError) |
|
41 |
|
|
42 |
API_Spec = QuotaholderAPI |
/dev/null | ||
---|---|---|
1 |
# Copyright 2012 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from synnefo.lib.commissioning import (CallError, register_exception, |
|
35 |
InvalidDataError, CorruptedError) |
|
36 |
|
|
37 |
@register_exception |
|
38 |
class CommissionException(CallError): |
|
39 |
pass |
|
40 |
|
|
41 |
@register_exception |
|
42 |
class InvalidKeyError(CommissionException): |
|
43 |
pass |
|
44 |
|
|
45 |
@register_exception |
|
46 |
class NoEntityError(CommissionException): |
|
47 |
pass |
|
48 |
|
|
49 |
@register_exception |
|
50 |
class CommissionValueException(CommissionException): |
|
51 |
def __init__(self, *args, **kw): |
|
52 |
super(CommissionValueException, self).__init__(*args, **kw) |
|
53 |
kwargs = self.kwargs |
|
54 |
|
|
55 |
self.source = kwargs['source'] |
|
56 |
self.target = kwargs['target'] |
|
57 |
self.resource = kwargs['resource'] |
|
58 |
self.requested = kwargs['requested'] |
|
59 |
self.current = kwargs['current'] |
|
60 |
self.limit = kwargs['limit'] |
|
61 |
|
|
62 |
@register_exception |
|
63 |
class NoQuantityError(CommissionValueException): |
|
64 |
pass |
|
65 |
|
|
66 |
@register_exception |
|
67 |
class NoCapacityError(CommissionValueException): |
|
68 |
pass |
|
69 |
|
|
70 |
@register_exception |
|
71 |
class ExportLimitError(CommissionValueException): |
|
72 |
pass |
|
73 |
|
|
74 |
@register_exception |
|
75 |
class ImportLimitError(CommissionValueException): |
|
76 |
pass |
|
77 |
|
|
78 |
@register_exception |
|
79 |
class DuplicateError(CommissionException): |
|
80 |
pass |
/dev/null | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# |
|
3 |
# Copyright 2012 GRNET S.A. All rights reserved. |
|
4 |
# |
|
5 |
# Redistribution and use in source and binary forms, with or |
|
6 |
# without modification, are permitted provided that the following |
|
7 |
# conditions are met: |
|
8 |
# |
|
9 |
# 1. Redistributions of source code must retain the above |
|
10 |
# copyright notice, this list of conditions and the following |
|
11 |
# disclaimer. |
|
12 |
# |
|
13 |
# 2. Redistributions in binary form must reproduce the above |
|
14 |
# copyright notice, this list of conditions and the following |
|
15 |
# disclaimer in the documentation and/or other materials |
|
16 |
# provided with the distribution. |
|
17 |
# |
|
18 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
19 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
20 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
21 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
22 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
25 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
26 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
27 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
28 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
29 |
# POSSIBILITY OF SUCH DAMAGE. |
|
30 |
# |
|
31 |
# The views and conclusions contained in the software and |
|
32 |
# documentation are those of the authors and should not be |
|
33 |
# interpreted as representing official policies, either expressed |
|
34 |
# or implied, of GRNET S.A. |
|
35 |
|
|
36 |
|
|
37 |
from synnefo.lib.commissioning import (CanonifyException, SpecifyException, |
|
38 |
Specificator, Null, Integer, Text, |
|
39 |
Tuple, ListOf, Dict, Args) |
|
40 |
from random import choice, randint |
|
41 |
|
|
42 |
Context = Dict(classname='Context', null=True, show=False) |
|
43 |
|
|
44 |
class Name(Text): |
|
45 |
def init(self): |
|
46 |
self.opts.update({'regex': "[\w.:@+/-]+", 'maxlen':512}) |
|
47 |
Text.init(self) |
|
48 |
|
|
49 |
def _random_choice(self, kw): |
|
50 |
alphabet = u'abcdef_1233490.:@/-αβγδεζ' |
|
51 |
length = randint(1, 48) |
|
52 |
return ''.join(choice(alphabet) for _ in xrange(length)) |
|
53 |
|
|
54 |
class Nonnegative(Integer): |
|
55 |
def init(self): |
|
56 |
self.opts.update({'minimum': 0}) |
|
57 |
|
|
58 |
class Positive(Integer): |
|
59 |
def init(self): |
|
60 |
self.opts.update({'minimum': 1}) |
|
61 |
|
|
62 |
QH_PRACTICALLY_INFINITE = 10**32 |
|
63 |
|
|
64 |
Serial = Positive(classname='Serial') |
|
65 |
|
|
66 |
ClientKey = Name(classname='ClientKey') |
|
67 |
Nothing = Null(classname='Nothing') |
|
68 |
|
|
69 |
Entity = Name(classname='Entity') |
|
70 |
Owner = Name(classname='Owner') |
|
71 |
Key = Text(classname='Key') |
|
72 |
NewKey = Text(classname='Newkey') |
|
73 |
OwnerKey = Text(classname='OwnerKey') |
|
74 |
Resource = Name(classname='Resource') |
|
75 |
Policy = Name(classname='Policy') |
|
76 |
|
|
77 |
Quantity = Integer(classname='Quantity') |
|
78 |
Capacity = Nonnegative(classname='Capacity') |
|
79 |
ImportLimit = Nonnegative(classname='ImportLimit') |
|
80 |
ExportLimit = Nonnegative(classname='ExportLimit') |
|
81 |
QuantityDelta = Integer(classname='QuantityDelta') |
|
82 |
CapacityDelta = Integer(classname='CapacityDelta') |
|
83 |
ImportLimitDelta = Integer(classname='ImportLimitDelta') |
|
84 |
ExportLimitDelta = Integer(classname='ExportLimitDelta') |
|
85 |
Imported = Nonnegative(classname='Imported') |
|
86 |
Exported = Nonnegative(classname='Exported') |
|
87 |
Returned = Nonnegative(classname='Returned') |
|
88 |
Released = Nonnegative(classname='Released') |
|
89 |
Flags = Nonnegative(classname='Flags') |
|
90 |
Index = Nonnegative(classname='Index') |
|
91 |
|
|
92 |
Timepoint = Text(classname='Timepoint', maxlen=24) |
|
93 |
Reason = Text( classname = 'Reason', |
|
94 |
regex = '(ACCEPT|REJECT):.*', |
|
95 |
maxlen = 128 ) |
|
96 |
|
|
97 |
class QuotaholderAPI(Specificator): |
|
98 |
|
|
99 |
def create_entity ( |
|
100 |
self, |
|
101 |
context = Context, |
|
102 |
create_entity = ListOf(Entity, Owner, Key, OwnerKey, nonempty=1) |
|
103 |
): |
|
104 |
rejected = ListOf(Index) |
|
105 |
return rejected |
|
106 |
|
|
107 |
def set_entity_key ( |
|
108 |
self, |
|
109 |
context = Context, |
|
110 |
set_entity_key = ListOf(Entity, Key, NewKey) |
|
111 |
): |
|
112 |
rejected = ListOf(Entity) |
|
113 |
return rejected |
|
114 |
|
|
115 |
def list_entities ( |
|
116 |
self, |
|
117 |
context = Context, |
|
118 |
entity = Entity, |
|
119 |
key = Key |
|
120 |
): |
|
121 |
entities = ListOf(Entity) |
|
122 |
return entities |
|
123 |
|
|
124 |
def get_entity ( |
|
125 |
self, |
|
126 |
context = Context, |
|
127 |
get_entity = ListOf(Entity, Key, nonempty=1) |
|
128 |
): |
|
129 |
entities = ListOf(Entity, Owner) |
|
130 |
return entities |
|
131 |
|
|
132 |
def get_limits ( |
|
133 |
self, |
|
134 |
context = Context, |
|
135 |
get_limits = ListOf(Policy, nonempty=1) |
|
136 |
): |
|
137 |
limits = ListOf(Policy, Quantity, Capacity, |
|
138 |
ImportLimit, ExportLimit) |
|
139 |
return limits |
|
140 |
|
|
141 |
def set_limits ( |
|
142 |
self, |
|
143 |
context = Context, |
|
144 |
set_limits = ListOf( Policy, Quantity, Capacity, |
|
145 |
ImportLimit, ExportLimit, |
|
146 |
nonempty=1 ) |
|
147 |
): |
|
148 |
rejected = ListOf(Policy) |
|
149 |
return rejected |
|
150 |
|
|
151 |
def get_holding ( |
|
152 |
self, |
|
153 |
context = Context, |
|
154 |
get_holding = ListOf(Entity, Resource, Key) |
|
155 |
): |
|
156 |
holdings = ListOf( Entity, Resource, Policy, |
|
157 |
Imported, Exported, Returned, Released, Flags ) |
|
158 |
return holdings |
|
159 |
|
|
160 |
def set_holding ( |
|
161 |
self, |
|
162 |
context = Context, |
|
163 |
set_holding = ListOf(Entity, Resource, Key, Policy, Flags) |
|
164 |
): |
|
165 |
rejected = ListOf(Entity, Resource, Policy) |
|
166 |
return rejected |
|
167 |
|
|
168 |
def init_holding ( |
|
169 |
self, |
|
170 |
context = Context, |
|
171 |
init_holding = ListOf(Entity, Resource, Key, Policy, |
|
172 |
Imported, Exported, Returned, Released, |
|
173 |
Flags) |
|
174 |
): |
|
175 |
rejected = ListOf(Index) |
|
176 |
return rejected |
|
177 |
|
|
178 |
def reset_holding ( |
|
179 |
self, |
|
180 |
context = Context, |
|
181 |
reset_holding = ListOf(Entity, Resource, Key, |
|
182 |
Imported, Exported, Returned, Released) |
|
183 |
): |
|
184 |
rejected = ListOf(Index) |
|
185 |
return rejected |
|
186 |
|
|
187 |
def release_holding ( |
|
188 |
self, |
|
189 |
context = Context, |
|
190 |
release_holding = ListOf(Entity, Resource, Key) |
|
191 |
): |
|
192 |
rejected = ListOf(Index) |
|
193 |
return rejected |
|
194 |
|
|
195 |
def list_resources ( |
|
196 |
self, |
|
197 |
context = Context, |
|
198 |
entity = Entity, |
|
199 |
key = Key |
|
200 |
): |
|
201 |
resources = ListOf(Resource) |
|
202 |
return resources |
|
203 |
|
|
204 |
def list_holdings ( |
|
205 |
self, |
|
206 |
context = Context, |
|
207 |
list_holdings = ListOf(Entity, Key) |
|
208 |
): |
|
209 |
|
|
210 |
rejected = ListOf(Entity) |
|
211 |
holdings_list = ListOf(ListOf(Entity, Resource, |
|
212 |
Imported, Exported, |
|
213 |
Returned, Released)) |
|
214 |
return Tuple(holdings_list, rejected) |
|
215 |
|
|
216 |
def get_quota ( |
|
217 |
self, |
|
218 |
context = Context, |
|
219 |
get_quota = ListOf(Entity, Resource, Key) |
|
220 |
): |
|
221 |
quotas = ListOf(Entity, Resource, |
|
222 |
Quantity, Capacity, |
|
223 |
ImportLimit, ExportLimit, |
|
224 |
Imported, Exported, |
|
225 |
Returned, Released, |
|
226 |
Flags) |
|
227 |
return quotas |
|
228 |
|
|
229 |
def set_quota ( |
|
230 |
self, |
|
231 |
context = Context, |
|
232 |
set_quota = ListOf( Entity, Resource, Key, |
|
233 |
Quantity, Capacity, |
|
234 |
ImportLimit, ExportLimit, Flags ) |
|
235 |
): |
|
236 |
rejected = ListOf(Entity, Resource) |
|
237 |
return rejected |
|
238 |
|
|
239 |
def add_quota ( |
|
240 |
self, |
|
241 |
context = Context, |
|
242 |
clientkey = ClientKey, |
|
243 |
serial = Serial, |
|
244 |
sub_quota = ListOf( Entity, Resource, Key, |
|
245 |
QuantityDelta, CapacityDelta, |
|
246 |
ImportLimitDelta, ExportLimitDelta ), |
|
247 |
add_quota = ListOf( Entity, Resource, Key, |
|
248 |
QuantityDelta, CapacityDelta, |
|
249 |
ImportLimitDelta, ExportLimitDelta ) |
|
250 |
): |
|
251 |
rejected = ListOf(Entity, Resource) |
|
252 |
return rejected |
|
253 |
|
|
254 |
def query_serials ( |
|
255 |
self, |
|
256 |
context = Context, |
|
257 |
clientkey = ClientKey, |
|
258 |
serials = ListOf(Serial) |
|
259 |
): |
|
260 |
return ListOf(Serial) |
|
261 |
|
|
262 |
def ack_serials ( |
|
263 |
self, |
|
264 |
context = Context, |
|
265 |
clientkey = ClientKey, |
|
266 |
serials = ListOf(Serial) |
|
267 |
): |
|
268 |
return Nothing |
|
269 |
|
|
270 |
def issue_commission ( |
|
271 |
self, |
|
272 |
context = Context, |
|
273 |
target = Entity, |
|
274 |
key = Key, |
|
275 |
clientkey = ClientKey, |
|
276 |
name = Text(default=''), |
|
277 |
provisions = ListOf(Entity, Resource, Quantity) |
|
278 |
): |
|
279 |
return Serial |
|
280 |
|
|
281 |
def accept_commission ( |
|
282 |
self, |
|
283 |
context = Context, |
|
284 |
clientkey = ClientKey, |
|
285 |
serials = ListOf(Serial), |
|
286 |
reason = Text(default='ACCEPT') |
|
287 |
): |
|
288 |
return Nothing |
|
289 |
|
|
290 |
def reject_commission ( |
|
291 |
self, |
|
292 |
context = Context, |
|
293 |
clientkey = ClientKey, |
|
294 |
serials = ListOf(Serial), |
|
295 |
reason = Text(default='REJECT') |
|
296 |
): |
|
297 |
return Nothing |
|
298 |
|
|
299 |
def get_pending_commissions ( |
|
300 |
self, |
|
301 |
context = Context, |
|
302 |
clientkey = ClientKey |
|
303 |
): |
|
304 |
pending = ListOf(Serial) |
|
305 |
return pending |
|
306 |
|
|
307 |
def resolve_pending_commissions ( |
|
308 |
self, |
|
309 |
context = Context, |
|
310 |
clientkey = ClientKey, |
|
311 |
max_serial = Serial, |
|
312 |
accept_set = ListOf(Serial) |
|
313 |
): |
|
314 |
return Nothing |
|
315 |
|
|
316 |
def release_entity ( |
|
317 |
self, |
|
318 |
context = Context, |
|
319 |
release_entity = ListOf(Entity, Key, nonempty=1) |
|
320 |
): |
|
321 |
rejected = ListOf(Entity) |
|
322 |
return rejected |
|
323 |
|
|
324 |
def get_timeline ( |
|
325 |
self, |
|
326 |
context = Context, |
|
327 |
after = Timepoint, |
|
328 |
before = Timepoint, |
|
329 |
get_timeline = ListOf(Entity, Resource, Key) |
|
330 |
): |
|
331 |
timeline = ListOf(Dict( |
|
332 |
serial = Serial, |
|
333 |
source = Entity, |
|
334 |
target = Entity, |
|
335 |
resource = Resource, |
|
336 |
name = Name(), |
|
337 |
quantity = Quantity, |
|
338 |
source_allocated = Quantity, |
|
339 |
source_allocated_through = Quantity, |
|
340 |
source_inbound = Quantity, |
|
341 |
source_inbound_through = Quantity, |
|
342 |
source_outbound = Quantity, |
|
343 |
source_outbound_through = Quantity, |
|
344 |
target_allocated = Quantity, |
|
345 |
target_allocated_through = Quantity, |
|
346 |
target_inbound = Quantity, |
|
347 |
target_inbound_through = Quantity, |
|
348 |
target_outbound = Quantity, |
|
349 |
target_outbound_through = Quantity, |
|
350 |
issue_time = Timepoint, |
|
351 |
log_time = Timepoint, |
|
352 |
reason = Reason, |
|
353 |
|
|
354 |
strict = True)) |
|
355 |
return timeline |
|
356 |
|
/dev/null | ||
---|---|---|
1 |
# Copyright 2012 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from synnefo.lib.commissioning import Callpoint, CallError |
|
35 |
from objpool.http import PooledHTTPConnection |
|
36 |
from .api import QuotaholderAPI |
|
37 |
|
|
38 |
from json import loads as json_loads, dumps as json_dumps |
|
39 |
import logging |
|
40 |
from urlparse import urlparse |
|
41 |
|
|
42 |
logger = logging.getLogger(__name__) |
|
43 |
|
|
44 |
|
|
45 |
class QuotaholderClient(Callpoint): |
|
46 |
|
|
47 |
api_spec = QuotaholderAPI() |
|
48 |
|
|
49 |
def __init__(self, base_url, token='', poolsize=1000): |
|
50 |
super(QuotaholderClient, self).__init__() |
|
51 |
self._url = base_url |
|
52 |
parsed = urlparse(base_url) |
|
53 |
self._netloc = parsed.netloc |
|
54 |
self._scheme = parsed.scheme |
|
55 |
basepath = parsed.path |
|
56 |
if not basepath.endswith('/'): |
|
57 |
basepath += '/' |
|
58 |
self._basepath = basepath |
|
59 |
self._token = token |
|
60 |
self._poolsize = poolsize |
|
61 |
|
|
62 |
def do_make_call(self, api_call, data): |
|
63 |
|
|
64 |
gettable = ['list', 'get', 'read'] |
|
65 |
method = ('GET' if any(api_call.startswith(x) for x in gettable) |
|
66 |
else 'POST') |
|
67 |
|
|
68 |
path = self._basepath + api_call |
|
69 |
json_data = json_dumps(data) |
|
70 |
|
|
71 |
logger.debug("%s %s\n%s\n<<<\n", method, path, json_data[:128]) |
|
72 |
headers = {'X-Auth-Token': self._token} |
|
73 |
with PooledHTTPConnection(scheme=self._scheme, |
|
74 |
netloc=self._netloc, |
|
75 |
size=self._poolsize) as conn: |
|
76 |
conn.request(method, path, body=json_data, headers=headers) |
|
77 |
resp = conn.getresponse() |
|
78 |
body = resp.read() |
|
79 |
|
|
80 |
logger.debug(">>>\nStatus: %s", resp.status) |
|
81 |
logger.debug("\n%s\n<<<\n", body[:128] if body else None) |
|
82 |
|
|
83 |
status = int(resp.status) |
|
84 |
if status == 200: |
|
85 |
return json_loads(body) |
|
86 |
else: |
|
87 |
try: |
|
88 |
error = json_loads(body) |
|
89 |
except ValueError: |
|
90 |
exc = CallError(body, call_error='ValueError') |
|
91 |
else: |
|
92 |
exc = CallError.from_dict(error) |
|
93 |
raise exc |
Also available in: Unified diff