root / snf-cyclades-app / synnefo / quotas / __init__.py @ 498b2bd0
History | View | Annotate | Download (11.7 kB)
1 | bfe7ba3c | Christos Stavrakakis | # Copyright 2012 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | bfe7ba3c | Christos Stavrakakis | #
|
3 | bfe7ba3c | Christos Stavrakakis | # Redistribution and use in source and binary forms, with or without
|
4 | bfe7ba3c | Christos Stavrakakis | # modification, are permitted provided that the following conditions
|
5 | bfe7ba3c | Christos Stavrakakis | # are met:
|
6 | bfe7ba3c | Christos Stavrakakis | #
|
7 | bfe7ba3c | Christos Stavrakakis | # 1. Redistributions of source code must retain the above copyright
|
8 | bfe7ba3c | Christos Stavrakakis | # notice, this list of conditions and the following disclaimer.
|
9 | bfe7ba3c | Christos Stavrakakis | #
|
10 | bfe7ba3c | Christos Stavrakakis | # 2. Redistributions in binary form must reproduce the above copyright
|
11 | bfe7ba3c | Christos Stavrakakis | # notice, this list of conditions and the following disclaimer in the
|
12 | bfe7ba3c | Christos Stavrakakis | # documentation and/or other materials provided with the distribution.
|
13 | bfe7ba3c | Christos Stavrakakis | #
|
14 | bfe7ba3c | Christos Stavrakakis | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
15 | bfe7ba3c | Christos Stavrakakis | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16 | bfe7ba3c | Christos Stavrakakis | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17 | bfe7ba3c | Christos Stavrakakis | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
18 | bfe7ba3c | Christos Stavrakakis | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19 | bfe7ba3c | Christos Stavrakakis | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
20 | bfe7ba3c | Christos Stavrakakis | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
21 | bfe7ba3c | Christos Stavrakakis | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
22 | bfe7ba3c | Christos Stavrakakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
23 | bfe7ba3c | Christos Stavrakakis | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
24 | bfe7ba3c | Christos Stavrakakis | # SUCH DAMAGE.
|
25 | bfe7ba3c | Christos Stavrakakis | #
|
26 | bfe7ba3c | Christos Stavrakakis | # The views and conclusions contained in the software and documentation are
|
27 | bfe7ba3c | Christos Stavrakakis | # those of the authors and should not be interpreted as representing official
|
28 | bfe7ba3c | Christos Stavrakakis | # policies, either expressed or implied, of GRNET S.A.
|
29 | bfe7ba3c | Christos Stavrakakis | |
30 | bfe7ba3c | Christos Stavrakakis | from functools import wraps |
31 | bfe7ba3c | Christos Stavrakakis | from contextlib import contextmanager |
32 | bfe7ba3c | Christos Stavrakakis | |
33 | b14f55b5 | Christos Stavrakakis | |
34 | b14f55b5 | Christos Stavrakakis | from synnefo.db.models import QuotaHolderSerial, VirtualMachine, Network |
35 | bfe7ba3c | Christos Stavrakakis | from synnefo.api.faults import OverLimit |
36 | 6dbd90c0 | Christos Stavrakakis | from synnefo.settings import CYCLADES_USE_QUOTAHOLDER |
37 | 6dbd90c0 | Christos Stavrakakis | |
38 | 6dbd90c0 | Christos Stavrakakis | if CYCLADES_USE_QUOTAHOLDER:
|
39 | 6dbd90c0 | Christos Stavrakakis | from synnefo.settings import (CYCLADES_QUOTAHOLDER_URL, |
40 | 6dbd90c0 | Christos Stavrakakis | CYCLADES_QUOTAHOLDER_TOKEN) |
41 | 6dbd90c0 | Christos Stavrakakis | from kamaki.clients.quotaholder import QuotaholderClient |
42 | 6dbd90c0 | Christos Stavrakakis | else:
|
43 | 6dbd90c0 | Christos Stavrakakis | from synnefo.settings import (VMS_USER_QUOTA, MAX_VMS_PER_USER, |
44 | 6dbd90c0 | Christos Stavrakakis | NETWORKS_USER_QUOTA, MAX_NETWORKS_PER_USER) |
45 | bfe7ba3c | Christos Stavrakakis | |
46 | 498b2bd0 | Georgios D. Tsoukalas | from kamaki.clients.quotaholder.api import (NoCapacityError, NoQuantityError, |
47 | 498b2bd0 | Georgios D. Tsoukalas | NoEntityError) |
48 | 7f849a28 | Georgios D. Tsoukalas | from kamaki.clients.commissioning import CallError |
49 | bfe7ba3c | Christos Stavrakakis | |
50 | bfe7ba3c | Christos Stavrakakis | import logging |
51 | bfe7ba3c | Christos Stavrakakis | log = logging.getLogger(__name__) |
52 | bfe7ba3c | Christos Stavrakakis | |
53 | bfe7ba3c | Christos Stavrakakis | |
54 | b14f55b5 | Christos Stavrakakis | class DummySerial(QuotaHolderSerial): |
55 | b14f55b5 | Christos Stavrakakis | accepted = True
|
56 | b14f55b5 | Christos Stavrakakis | rejected = True
|
57 | b14f55b5 | Christos Stavrakakis | pending = True
|
58 | b14f55b5 | Christos Stavrakakis | id = None
|
59 | b14f55b5 | Christos Stavrakakis | |
60 | b14f55b5 | Christos Stavrakakis | def save(*args, **kwargs): |
61 | b14f55b5 | Christos Stavrakakis | pass
|
62 | b14f55b5 | Christos Stavrakakis | |
63 | b14f55b5 | Christos Stavrakakis | |
64 | b14f55b5 | Christos Stavrakakis | class DummyQuotaholderClient(object): |
65 | b14f55b5 | Christos Stavrakakis | def issue_commission(self, **commission_info): |
66 | b14f55b5 | Christos Stavrakakis | provisions = commission_info["provisions"]
|
67 | b14f55b5 | Christos Stavrakakis | userid = commission_info["target"]
|
68 | b14f55b5 | Christos Stavrakakis | for provision in provisions: |
69 | b14f55b5 | Christos Stavrakakis | entity, resource, size = provision |
70 | e8f8f4aa | Christos Stavrakakis | if resource == "cyclades.vm" and size > 0: |
71 | b14f55b5 | Christos Stavrakakis | user_vms = VirtualMachine.objects.filter(userid=userid, |
72 | b14f55b5 | Christos Stavrakakis | deleted=False).count()
|
73 | b14f55b5 | Christos Stavrakakis | user_vm_limit = VMS_USER_QUOTA.get(userid, MAX_VMS_PER_USER) |
74 | 718a601d | root | log.debug("Users VMs %s User Limits %s", user_vms,
|
75 | 718a601d | root | user_vm_limit) |
76 | 5a70b1a3 | Christos Stavrakakis | if user_vms + size > user_vm_limit:
|
77 | 5a70b1a3 | Christos Stavrakakis | raise NoQuantityError(source='cyclades', |
78 | 5a70b1a3 | Christos Stavrakakis | target=userid, |
79 | 5a70b1a3 | Christos Stavrakakis | resource=resource, |
80 | 5a70b1a3 | Christos Stavrakakis | requested=size, |
81 | 5a70b1a3 | Christos Stavrakakis | current=user_vms, |
82 | 5a70b1a3 | Christos Stavrakakis | limit=user_vm_limit) |
83 | e8f8f4aa | Christos Stavrakakis | if resource == "cyclades.network.private" and size > 0: |
84 | b14f55b5 | Christos Stavrakakis | user_networks = Network.objects.filter(userid=userid, |
85 | b14f55b5 | Christos Stavrakakis | deleted=False).count()
|
86 | 68b952f9 | Christos Stavrakakis | user_network_limit =\ |
87 | 68b952f9 | Christos Stavrakakis | NETWORKS_USER_QUOTA.get(userid, MAX_NETWORKS_PER_USER) |
88 | 5a70b1a3 | Christos Stavrakakis | if user_networks + size > user_network_limit:
|
89 | 5a70b1a3 | Christos Stavrakakis | raise NoQuantityError(source='cyclades', |
90 | 5a70b1a3 | Christos Stavrakakis | target=userid, |
91 | 5a70b1a3 | Christos Stavrakakis | resource=resource, |
92 | 5a70b1a3 | Christos Stavrakakis | requested=size, |
93 | 5a70b1a3 | Christos Stavrakakis | current=user_networks, |
94 | 5a70b1a3 | Christos Stavrakakis | limit=user_network_limit) |
95 | b14f55b5 | Christos Stavrakakis | |
96 | b14f55b5 | Christos Stavrakakis | return None |
97 | b14f55b5 | Christos Stavrakakis | |
98 | b14f55b5 | Christos Stavrakakis | def accept_commission(self, *args, **kwargs): |
99 | b14f55b5 | Christos Stavrakakis | pass
|
100 | b14f55b5 | Christos Stavrakakis | |
101 | b14f55b5 | Christos Stavrakakis | def reject_commission(self, *args, **kwargs): |
102 | b14f55b5 | Christos Stavrakakis | pass
|
103 | b14f55b5 | Christos Stavrakakis | |
104 | b14f55b5 | Christos Stavrakakis | def get_pending_commissions(self, *args, **kwargs): |
105 | b14f55b5 | Christos Stavrakakis | return []
|
106 | b14f55b5 | Christos Stavrakakis | |
107 | b14f55b5 | Christos Stavrakakis | |
108 | bfe7ba3c | Christos Stavrakakis | @contextmanager
|
109 | bfe7ba3c | Christos Stavrakakis | def get_quota_holder(): |
110 | bfe7ba3c | Christos Stavrakakis | """Context manager for using a QuotaHolder."""
|
111 | 45855947 | Georgios D. Tsoukalas | if CYCLADES_USE_QUOTAHOLDER:
|
112 | 45855947 | Georgios D. Tsoukalas | quotaholder = QuotaholderClient(CYCLADES_QUOTAHOLDER_URL, |
113 | 45855947 | Georgios D. Tsoukalas | token=CYCLADES_QUOTAHOLDER_TOKEN) |
114 | b14f55b5 | Christos Stavrakakis | else:
|
115 | b14f55b5 | Christos Stavrakakis | quotaholder = DummyQuotaholderClient() |
116 | bfe7ba3c | Christos Stavrakakis | |
117 | bfe7ba3c | Christos Stavrakakis | try:
|
118 | bfe7ba3c | Christos Stavrakakis | yield quotaholder
|
119 | bfe7ba3c | Christos Stavrakakis | finally:
|
120 | bfe7ba3c | Christos Stavrakakis | pass
|
121 | bfe7ba3c | Christos Stavrakakis | |
122 | bfe7ba3c | Christos Stavrakakis | |
123 | bfe7ba3c | Christos Stavrakakis | def uses_commission(func): |
124 | bfe7ba3c | Christos Stavrakakis | """Decorator for wrapping functions that needs commission.
|
125 | bfe7ba3c | Christos Stavrakakis |
|
126 | bfe7ba3c | Christos Stavrakakis | All decorated functions must take as first argument the `serials` list in
|
127 | bfe7ba3c | Christos Stavrakakis | order to extend them with the needed serial numbers, as return by the
|
128 | bfe7ba3c | Christos Stavrakakis | Quotaholder
|
129 | bfe7ba3c | Christos Stavrakakis |
|
130 | bfe7ba3c | Christos Stavrakakis | On successful competition of the decorated function, all serials are
|
131 | bfe7ba3c | Christos Stavrakakis | accepted to the quotaholder, otherwise they are rejected.
|
132 | bfe7ba3c | Christos Stavrakakis |
|
133 | bfe7ba3c | Christos Stavrakakis | """
|
134 | bfe7ba3c | Christos Stavrakakis | |
135 | bfe7ba3c | Christos Stavrakakis | @wraps(func)
|
136 | bfe7ba3c | Christos Stavrakakis | def wrapper(*args, **kwargs): |
137 | bfe7ba3c | Christos Stavrakakis | try:
|
138 | bfe7ba3c | Christos Stavrakakis | serials = [] |
139 | bfe7ba3c | Christos Stavrakakis | ret = func(serials, *args, **kwargs) |
140 | bfe7ba3c | Christos Stavrakakis | if serials:
|
141 | bfe7ba3c | Christos Stavrakakis | accept_commission(serials) |
142 | bfe7ba3c | Christos Stavrakakis | return ret
|
143 | e8f2d02d | Christos Stavrakakis | except CallError:
|
144 | bfe7ba3c | Christos Stavrakakis | log.exception("Unexpected error")
|
145 | b14f55b5 | Christos Stavrakakis | raise
|
146 | bfe7ba3c | Christos Stavrakakis | except:
|
147 | bfe7ba3c | Christos Stavrakakis | if serials:
|
148 | bfe7ba3c | Christos Stavrakakis | reject_commission(serials=serials) |
149 | bfe7ba3c | Christos Stavrakakis | raise
|
150 | bfe7ba3c | Christos Stavrakakis | return wrapper
|
151 | bfe7ba3c | Christos Stavrakakis | |
152 | bfe7ba3c | Christos Stavrakakis | |
153 | bfe7ba3c | Christos Stavrakakis | ## FIXME: Wrap the following two functions inside transaction ?
|
154 | 11a54cb9 | Christos Stavrakakis | def accept_commission(serials, update_db=True): |
155 | bfe7ba3c | Christos Stavrakakis | """Accept a list of pending commissions.
|
156 | bfe7ba3c | Christos Stavrakakis |
|
157 | bfe7ba3c | Christos Stavrakakis | @param serials: List of QuotaHolderSerial objects
|
158 | bfe7ba3c | Christos Stavrakakis |
|
159 | bfe7ba3c | Christos Stavrakakis | """
|
160 | 11a54cb9 | Christos Stavrakakis | if update_db:
|
161 | 11a54cb9 | Christos Stavrakakis | for s in serials: |
162 | 11a54cb9 | Christos Stavrakakis | if s.pending:
|
163 | 11a54cb9 | Christos Stavrakakis | s.accepted = True
|
164 | 11a54cb9 | Christos Stavrakakis | s.save() |
165 | bfe7ba3c | Christos Stavrakakis | |
166 | bfe7ba3c | Christos Stavrakakis | with get_quota_holder() as qh: |
167 | bfe7ba3c | Christos Stavrakakis | qh.accept_commission(context={}, |
168 | bfe7ba3c | Christos Stavrakakis | clientkey='cyclades',
|
169 | bfe7ba3c | Christos Stavrakakis | serials=[s.serial for s in serials]) |
170 | bfe7ba3c | Christos Stavrakakis | |
171 | bfe7ba3c | Christos Stavrakakis | |
172 | 11a54cb9 | Christos Stavrakakis | def reject_commission(serials, update_db=True): |
173 | bfe7ba3c | Christos Stavrakakis | """Reject a list of pending commissions.
|
174 | bfe7ba3c | Christos Stavrakakis |
|
175 | bfe7ba3c | Christos Stavrakakis | @param serials: List of QuotaHolderSerial objects
|
176 | bfe7ba3c | Christos Stavrakakis |
|
177 | bfe7ba3c | Christos Stavrakakis | """
|
178 | 11a54cb9 | Christos Stavrakakis | if update_db:
|
179 | 11a54cb9 | Christos Stavrakakis | for s in serials: |
180 | 11a54cb9 | Christos Stavrakakis | if s.pending:
|
181 | 11a54cb9 | Christos Stavrakakis | s.rejected = True
|
182 | 11a54cb9 | Christos Stavrakakis | s.save() |
183 | bfe7ba3c | Christos Stavrakakis | |
184 | bfe7ba3c | Christos Stavrakakis | with get_quota_holder() as qh: |
185 | bfe7ba3c | Christos Stavrakakis | qh.reject_commission(context={}, |
186 | bfe7ba3c | Christos Stavrakakis | clientkey='cyclades',
|
187 | bfe7ba3c | Christos Stavrakakis | serials=[s.serial for s in serials]) |
188 | bfe7ba3c | Christos Stavrakakis | |
189 | bfe7ba3c | Christos Stavrakakis | |
190 | bfe7ba3c | Christos Stavrakakis | def issue_commission(**commission_info): |
191 | bfe7ba3c | Christos Stavrakakis | """Issue a new commission to the quotaholder.
|
192 | bfe7ba3c | Christos Stavrakakis |
|
193 | bfe7ba3c | Christos Stavrakakis | Issue a new commission to the quotaholder, and create the
|
194 | bfe7ba3c | Christos Stavrakakis | corresponing QuotaHolderSerial object in DB.
|
195 | bfe7ba3c | Christos Stavrakakis |
|
196 | bfe7ba3c | Christos Stavrakakis | """
|
197 | bfe7ba3c | Christos Stavrakakis | |
198 | bfe7ba3c | Christos Stavrakakis | with get_quota_holder() as qh: |
199 | bfe7ba3c | Christos Stavrakakis | try:
|
200 | bfe7ba3c | Christos Stavrakakis | serial = qh.issue_commission(**commission_info) |
201 | 5a70b1a3 | Christos Stavrakakis | except (NoCapacityError, NoQuantityError) as e: |
202 | 5a70b1a3 | Christos Stavrakakis | msg, details = render_quotaholder_exception(e) |
203 | 5a70b1a3 | Christos Stavrakakis | raise OverLimit(msg, details=details)
|
204 | e8f2d02d | Christos Stavrakakis | except CallError as e: |
205 | 5a70b1a3 | Christos Stavrakakis | log.exception("Unexpected error")
|
206 | 6dbd90c0 | Christos Stavrakakis | raise
|
207 | bfe7ba3c | Christos Stavrakakis | |
208 | b14f55b5 | Christos Stavrakakis | if serial:
|
209 | b14f55b5 | Christos Stavrakakis | return QuotaHolderSerial.objects.create(serial=serial)
|
210 | 718a601d | root | elif not CYCLADES_USE_QUOTAHOLDER: |
211 | b14f55b5 | Christos Stavrakakis | return DummySerial()
|
212 | b14f55b5 | Christos Stavrakakis | else:
|
213 | b14f55b5 | Christos Stavrakakis | raise Exception("No serial") |
214 | bfe7ba3c | Christos Stavrakakis | |
215 | bfe7ba3c | Christos Stavrakakis | |
216 | bfe7ba3c | Christos Stavrakakis | # Wrapper functions for issuing commissions for each resource type. Each
|
217 | bfe7ba3c | Christos Stavrakakis | # functions creates the `commission_info` dictionary as expected by the
|
218 | bfe7ba3c | Christos Stavrakakis | # `issue_commision` function. Commissions for deleting a resource, are the same
|
219 | bfe7ba3c | Christos Stavrakakis | # as for creating the same resource, but with negative resource sizes.
|
220 | bfe7ba3c | Christos Stavrakakis | |
221 | bfe7ba3c | Christos Stavrakakis | |
222 | bfe7ba3c | Christos Stavrakakis | def issue_vm_commission(user, flavor, delete=False): |
223 | bfe7ba3c | Christos Stavrakakis | resources = get_server_resources(flavor) |
224 | bfe7ba3c | Christos Stavrakakis | commission_info = create_commission(user, resources, delete) |
225 | bfe7ba3c | Christos Stavrakakis | |
226 | bfe7ba3c | Christos Stavrakakis | return issue_commission(**commission_info)
|
227 | bfe7ba3c | Christos Stavrakakis | |
228 | bfe7ba3c | Christos Stavrakakis | |
229 | bfe7ba3c | Christos Stavrakakis | def get_server_resources(flavor): |
230 | bfe7ba3c | Christos Stavrakakis | return {'vm': 1, |
231 | bfe7ba3c | Christos Stavrakakis | 'cpu': flavor.cpu,
|
232 | 457a8ada | Christos Stavrakakis | 'disk': 1073741824 * flavor.disk, # flavor.disk is in GB |
233 | bfe7ba3c | Christos Stavrakakis | # 'public_ip': 1,
|
234 | bfe7ba3c | Christos Stavrakakis | #'disk_template': flavor.disk_template,
|
235 | 5805fbb1 | Christos Stavrakakis | 'ram': 1048576 * flavor.ram} # flavor.ram is in MB |
236 | bfe7ba3c | Christos Stavrakakis | |
237 | bfe7ba3c | Christos Stavrakakis | |
238 | bfe7ba3c | Christos Stavrakakis | def issue_network_commission(user, delete=False): |
239 | bfe7ba3c | Christos Stavrakakis | resources = get_network_resources() |
240 | bfe7ba3c | Christos Stavrakakis | commission_info = create_commission(user, resources, delete) |
241 | bfe7ba3c | Christos Stavrakakis | |
242 | bfe7ba3c | Christos Stavrakakis | return issue_commission(**commission_info)
|
243 | bfe7ba3c | Christos Stavrakakis | |
244 | bfe7ba3c | Christos Stavrakakis | |
245 | bfe7ba3c | Christos Stavrakakis | def get_network_resources(): |
246 | bfe7ba3c | Christos Stavrakakis | return {"network.private": 1} |
247 | bfe7ba3c | Christos Stavrakakis | |
248 | bfe7ba3c | Christos Stavrakakis | |
249 | bfe7ba3c | Christos Stavrakakis | def invert_resources(resources_dict): |
250 | bfe7ba3c | Christos Stavrakakis | return dict((r, -s) for r, s in resources_dict.items()) |
251 | bfe7ba3c | Christos Stavrakakis | |
252 | bfe7ba3c | Christos Stavrakakis | |
253 | bfe7ba3c | Christos Stavrakakis | def create_commission(user, resources, delete=False): |
254 | bfe7ba3c | Christos Stavrakakis | if delete:
|
255 | bfe7ba3c | Christos Stavrakakis | resources = invert_resources(resources) |
256 | 4ac68aaf | Christos Stavrakakis | provisions = [('cyclades', 'cyclades.' + r, s) |
257 | bfe7ba3c | Christos Stavrakakis | for r, s in resources.items()] |
258 | 68b952f9 | Christos Stavrakakis | return {"context": {}, |
259 | 68b952f9 | Christos Stavrakakis | "target": user,
|
260 | 68b952f9 | Christos Stavrakakis | "key": "1", |
261 | 68b952f9 | Christos Stavrakakis | "clientkey": "cyclades", |
262 | 68b952f9 | Christos Stavrakakis | #"owner": "",
|
263 | 68b952f9 | Christos Stavrakakis | #"ownerkey": "1",
|
264 | 68b952f9 | Christos Stavrakakis | "name": "", |
265 | 68b952f9 | Christos Stavrakakis | "provisions": provisions}
|
266 | 11a54cb9 | Christos Stavrakakis | |
267 | 11a54cb9 | Christos Stavrakakis | ##
|
268 | 11a54cb9 | Christos Stavrakakis | ## Reconcile pending commissions
|
269 | 11a54cb9 | Christos Stavrakakis | ##
|
270 | 11a54cb9 | Christos Stavrakakis | |
271 | 11a54cb9 | Christos Stavrakakis | |
272 | 11a54cb9 | Christos Stavrakakis | def accept_commissions(accepted): |
273 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
274 | 11a54cb9 | Christos Stavrakakis | qh.accept_commission(context={}, |
275 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
276 | 11a54cb9 | Christos Stavrakakis | serials=accepted) |
277 | 11a54cb9 | Christos Stavrakakis | |
278 | 11a54cb9 | Christos Stavrakakis | |
279 | 11a54cb9 | Christos Stavrakakis | def reject_commissions(rejected): |
280 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
281 | 11a54cb9 | Christos Stavrakakis | qh.reject_commission(context={}, |
282 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
283 | 11a54cb9 | Christos Stavrakakis | serials=rejected) |
284 | 11a54cb9 | Christos Stavrakakis | |
285 | 11a54cb9 | Christos Stavrakakis | |
286 | 11a54cb9 | Christos Stavrakakis | def fix_pending_commissions(): |
287 | 11a54cb9 | Christos Stavrakakis | (accepted, rejected) = resolve_pending_commissions() |
288 | 11a54cb9 | Christos Stavrakakis | |
289 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
290 | 11a54cb9 | Christos Stavrakakis | if accepted:
|
291 | 11a54cb9 | Christos Stavrakakis | qh.accept_commission(context={}, |
292 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
293 | 11a54cb9 | Christos Stavrakakis | serials=accepted) |
294 | 11a54cb9 | Christos Stavrakakis | if rejected:
|
295 | 11a54cb9 | Christos Stavrakakis | qh.reject_commission(context={}, |
296 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
297 | 11a54cb9 | Christos Stavrakakis | serials=rejected) |
298 | 11a54cb9 | Christos Stavrakakis | |
299 | 11a54cb9 | Christos Stavrakakis | |
300 | 11a54cb9 | Christos Stavrakakis | def resolve_pending_commissions(): |
301 | 11a54cb9 | Christos Stavrakakis | """Resolve quotaholder pending commissions.
|
302 | 11a54cb9 | Christos Stavrakakis |
|
303 | 11a54cb9 | Christos Stavrakakis | Get pending commissions from the quotaholder and resolve them
|
304 | 11a54cb9 | Christos Stavrakakis | to accepted and rejected, according to the state of the
|
305 | 11a54cb9 | Christos Stavrakakis | QuotaHolderSerial DB table. A pending commission in the quotaholder
|
306 | 11a54cb9 | Christos Stavrakakis | can exist in the QuotaHolderSerial table and be either accepted or
|
307 | 11a54cb9 | Christos Stavrakakis | rejected, or can not exist in this table, so it is rejected.
|
308 | 11a54cb9 | Christos Stavrakakis |
|
309 | 11a54cb9 | Christos Stavrakakis | """
|
310 | 11a54cb9 | Christos Stavrakakis | |
311 | 11a54cb9 | Christos Stavrakakis | qh_pending = get_quotaholder_pending() |
312 | 11a54cb9 | Christos Stavrakakis | if not qh_pending: |
313 | 11a54cb9 | Christos Stavrakakis | return ([], [])
|
314 | 11a54cb9 | Christos Stavrakakis | |
315 | 11a54cb9 | Christos Stavrakakis | qh_pending.sort() |
316 | 11a54cb9 | Christos Stavrakakis | min_ = qh_pending[0]
|
317 | 11a54cb9 | Christos Stavrakakis | |
318 | 11a54cb9 | Christos Stavrakakis | serials = QuotaHolderSerial.objects.filter(serial__gte=min_, pending=False)
|
319 | 11a54cb9 | Christos Stavrakakis | accepted = serials.filter(accepted=True).values_list('serial', flat=True) |
320 | 11a54cb9 | Christos Stavrakakis | accepted = filter(lambda x: x in qh_pending, accepted) |
321 | 11a54cb9 | Christos Stavrakakis | |
322 | 11a54cb9 | Christos Stavrakakis | rejected = list(set(qh_pending) - set(accepted)) |
323 | 11a54cb9 | Christos Stavrakakis | |
324 | 11a54cb9 | Christos Stavrakakis | return (accepted, rejected)
|
325 | 11a54cb9 | Christos Stavrakakis | |
326 | 11a54cb9 | Christos Stavrakakis | |
327 | 11a54cb9 | Christos Stavrakakis | def get_quotaholder_pending(): |
328 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
329 | 11a54cb9 | Christos Stavrakakis | pending_serials = qh.get_pending_commissions(context={}, |
330 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades')
|
331 | 11a54cb9 | Christos Stavrakakis | return pending_serials
|
332 | 5a70b1a3 | Christos Stavrakakis | |
333 | 5a70b1a3 | Christos Stavrakakis | |
334 | 5a70b1a3 | Christos Stavrakakis | def render_quotaholder_exception(e): |
335 | 5a70b1a3 | Christos Stavrakakis | resource_name = {"vm": "Virtual Machine", |
336 | 5a70b1a3 | Christos Stavrakakis | "cpu": "CPU", |
337 | 5a70b1a3 | Christos Stavrakakis | "ram": "RAM", |
338 | 5a70b1a3 | Christos Stavrakakis | "network.private": "Private Network"} |
339 | 5a70b1a3 | Christos Stavrakakis | res = e.resource.replace("cyclades.", "", 1) |
340 | 5a70b1a3 | Christos Stavrakakis | try:
|
341 | 5a70b1a3 | Christos Stavrakakis | resource = resource_name[res] |
342 | 5a70b1a3 | Christos Stavrakakis | except KeyError: |
343 | 5a70b1a3 | Christos Stavrakakis | resource = res |
344 | 5a70b1a3 | Christos Stavrakakis | |
345 | 5a70b1a3 | Christos Stavrakakis | requested = e.requested |
346 | 5a70b1a3 | Christos Stavrakakis | current = e.current |
347 | 5a70b1a3 | Christos Stavrakakis | limit = e.limit |
348 | 5a70b1a3 | Christos Stavrakakis | msg = "Resource Limit Exceeded for your account."
|
349 | 5a70b1a3 | Christos Stavrakakis | details = "Limit for resource '%s' exceeded for your account."\
|
350 | 5a70b1a3 | Christos Stavrakakis | " Current value: %s, Limit: %s, Requested: %s"\
|
351 | 5a70b1a3 | Christos Stavrakakis | % (resource, current, limit, requested) |
352 | 5a70b1a3 | Christos Stavrakakis | return msg, details |