Revision 656cf771
b/snf-cyclades-app/synnefo/quotas/__init__.py | ||
---|---|---|
28 | 28 |
# policies, either expressed or implied, of GRNET S.A. |
29 | 29 |
|
30 | 30 |
from functools import wraps |
31 |
from contextlib import contextmanager
|
|
31 |
from django.utils import simplejson as json
|
|
32 | 32 |
|
33 | 33 |
from snf_django.lib.api import faults |
34 | 34 |
from synnefo.db.models import QuotaHolderSerial |
... | ... | |
43 | 43 |
log = logging.getLogger(__name__) |
44 | 44 |
|
45 | 45 |
DEFAULT_SOURCE = 'system' |
46 |
RESOURCES = [ |
|
47 |
"cyclades.vm", |
|
48 |
"cyclades.cpu", |
|
49 |
"cyclades.disk", |
|
50 |
"cyclades.ram", |
|
51 |
"cyclades.network.private" |
|
52 |
] |
|
46 | 53 |
|
47 | 54 |
|
48 | 55 |
class Quotaholder(object): |
... | ... | |
163 | 170 |
|
164 | 171 |
|
165 | 172 |
def issue_vm_commission(user, flavor, delete=False): |
166 |
resources = prepare(get_server_resources(flavor), delete) |
|
173 |
resources = get_server_resources(flavor) |
|
174 |
if delete: |
|
175 |
resources = reverse_quantities(resources) |
|
167 | 176 |
return issue_commission(user, DEFAULT_SOURCE, resources) |
168 | 177 |
|
169 | 178 |
|
170 | 179 |
def get_server_resources(flavor): |
171 |
return {'vm': 1, |
|
172 |
'cpu': flavor.cpu, |
|
173 |
'disk': 1073741824 * flavor.disk, # flavor.disk is in GB |
|
180 |
return {'cyclades.vm': 1,
|
|
181 |
'cyclades.cpu': flavor.cpu,
|
|
182 |
'cyclades.disk': 1073741824 * flavor.disk, # flavor.disk is in GB
|
|
174 | 183 |
# 'public_ip': 1, |
175 | 184 |
#'disk_template': flavor.disk_template, |
176 |
'ram': 1048576 * flavor.ram} # flavor.ram is in MB |
|
185 |
'cyclades.ram': 1048576 * flavor.ram} # flavor.ram is in MB
|
|
177 | 186 |
|
178 | 187 |
|
179 | 188 |
def issue_network_commission(user, delete=False): |
180 |
resources = prepare(get_network_resources(), delete) |
|
189 |
resources = get_network_resources() |
|
190 |
if delete: |
|
191 |
resources = reverse_quantities(resources) |
|
181 | 192 |
return issue_commission(user, DEFAULT_SOURCE, resources) |
182 | 193 |
|
183 | 194 |
|
184 | 195 |
def get_network_resources(): |
185 |
return {"network.private": 1} |
|
196 |
return {"cyclades.network.private": 1}
|
|
186 | 197 |
|
187 | 198 |
|
188 |
def prepare(resources_dict, delete): |
|
189 |
if delete: |
|
190 |
return dict((r, -s) for r, s in resources_dict.items()) |
|
191 |
return resources_dict |
|
199 |
def reverse_quantities(resources): |
|
200 |
return dict((r, -s) for r, s in resources.items()) |
|
192 | 201 |
|
193 | 202 |
|
194 | 203 |
## |
... | ... | |
257 | 266 |
"cpu": "CPU", |
258 | 267 |
"ram": "RAM", |
259 | 268 |
"network.private": "Private Network"} |
260 |
details = e.details
|
|
269 |
details = json.loads(e.details)
|
|
261 | 270 |
data = details['overLimit']['data'] |
262 |
available = data['available'] |
|
271 |
usage = data["usage"] |
|
272 |
limit = data["limit"] |
|
273 |
available = limit - usage |
|
263 | 274 |
provision = data['provision'] |
264 | 275 |
requested = provision['quantity'] |
265 | 276 |
resource = provision['resource'] |
b/snf-cyclades-app/synnefo/quotas/tests.py | ||
---|---|---|
46 | 46 |
|
47 | 47 |
class GetDBHoldingsTestCase(TestCase): |
48 | 48 |
def test_no_holdings(self): |
49 |
users = ["dummy_user1", "dummy_user2"] |
|
50 |
holdings = util.get_db_holdings(users=users) |
|
49 |
holdings = util.get_db_holdings(user=None) |
|
51 | 50 |
self.assertEqual(holdings, {}) |
52 | 51 |
|
53 | 52 |
def test_vm_holdings(self): |
... | ... | |
55 | 54 |
disk_template='drbd') |
56 | 55 |
mfactory.VirtualMachineFactory() |
57 | 56 |
mfactory.VirtualMachineFactory(flavor=flavor, userid="user1") |
58 |
user_holdings = {"user1": {"vm": 1, |
|
59 |
"cpu": 24, |
|
60 |
"disk": 21474836480, |
|
61 |
"ram": 8589934592}} |
|
62 |
holdings = util.get_db_holdings(users=["user1"])
|
|
57 |
user_holdings = {"user1": {"cyclades.vm": 1,
|
|
58 |
"cyclades.cpu": 24,
|
|
59 |
"cyclades.disk": 21474836480,
|
|
60 |
"cyclades.ram": 8589934592}}
|
|
61 |
holdings = util.get_db_holdings(user="user1")
|
|
63 | 62 |
self.assertEqual(holdings, user_holdings) |
64 | 63 |
holdings = util.get_db_holdings() |
65 | 64 |
self.assertEqual(holdings["user1"], user_holdings["user1"]) |
... | ... | |
67 | 66 |
def test_network_holdings(self): |
68 | 67 |
mfactory.NetworkFactory(userid="user1") |
69 | 68 |
mfactory.NetworkFactory(userid="user2") |
70 |
user_holdings = {"user2": {"network.private": 1}} |
|
71 |
holdings = util.get_db_holdings(users=["user2"])
|
|
69 |
user_holdings = {"user2": {"cyclades.network.private": 1}}
|
|
70 |
holdings = util.get_db_holdings(user="user2")
|
|
72 | 71 |
self.assertEqual(holdings, user_holdings) |
73 | 72 |
holdings = util.get_db_holdings() |
74 | 73 |
self.assertEqual(holdings["user2"], user_holdings["user2"]) |
b/snf-cyclades-app/synnefo/quotas/util.py | ||
---|---|---|
37 | 37 |
from synnefo.quotas import Quotaholder, ASTAKOS_TOKEN |
38 | 38 |
|
39 | 39 |
|
40 |
def get_db_holdings(users=None):
|
|
40 |
def get_db_holdings(user=None): |
|
41 | 41 |
"""Get holdings from Cyclades DB.""" |
42 | 42 |
holdings = {} |
43 | 43 |
|
44 | 44 |
vms = VirtualMachine.objects.filter(deleted=False) |
45 | 45 |
networks = Network.objects.filter(deleted=False) |
46 | 46 |
|
47 |
if users: |
|
48 |
assert(type(users) is list) |
|
49 |
vms = vms.filter(userid__in=users) |
|
50 |
networks = networks.filter(userid__in=users) |
|
47 |
if user is not None: |
|
48 |
vms = vms.filter(userid=user) |
|
49 |
networks = networks.filter(userid=user) |
|
51 | 50 |
|
52 | 51 |
# Get resources related with VMs |
53 | 52 |
vm_resources = vms.values("userid").annotate(num=Count("id"), |
... | ... | |
56 | 55 |
disk=Sum("flavor__disk")) |
57 | 56 |
for vm_res in vm_resources: |
58 | 57 |
user = vm_res['userid'] |
59 |
res = {"vm": vm_res["num"], |
|
60 |
"cpu": vm_res["cpu"], |
|
61 |
"disk": 1073741824 * vm_res["disk"], |
|
62 |
"ram": 1048576 * vm_res["ram"]} |
|
58 |
res = {"cyclades.vm": vm_res["num"],
|
|
59 |
"cyclades.cpu": vm_res["cpu"],
|
|
60 |
"cyclades.disk": 1073741824 * vm_res["disk"],
|
|
61 |
"cyclades.ram": 1048576 * vm_res["ram"]}
|
|
63 | 62 |
holdings[user] = res |
64 | 63 |
|
65 | 64 |
# Get resources related with networks |
... | ... | |
69 | 68 |
user = net_res['userid'] |
70 | 69 |
if user not in holdings: |
71 | 70 |
holdings[user] = {} |
72 |
holdings[user]["network.private"] = net_res["num"] |
|
71 |
holdings[user]["cyclades.network.private"] = net_res["num"]
|
|
73 | 72 |
|
74 | 73 |
return holdings |
75 | 74 |
|
... | ... | |
80 | 79 |
Returns quotas for all users, unless a single user is specified. |
81 | 80 |
""" |
82 | 81 |
qh = Quotaholder.get() |
83 |
return qh.get_service_quotas(ASTAKOS_TOKEN, user)
|
|
82 |
return qh.service_get_quotas(ASTAKOS_TOKEN, user)
|
|
84 | 83 |
|
85 | 84 |
|
86 | 85 |
def transform_quotas(quotas): |
87 | 86 |
d = {} |
88 | 87 |
for resource, counters in quotas.iteritems(): |
89 |
res = resource.replace("cyclades.", "") |
|
90 |
available = counters['available'] |
|
88 |
used = counters['usage'] |
|
91 | 89 |
limit = counters['limit'] |
92 |
used = counters['used'] |
|
93 |
used_max = limit - available |
|
94 |
d[res] = (used, used_max) |
|
90 |
pending = counters['pending'] |
|
91 |
d[resource] = (used, limit, pending) |
|
95 | 92 |
return d |
Also available in: Unified diff