Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / quotas.py @ 9202a57d

History | View | Annotate | Download (11.5 kB)

1 dc9da5b9 Giorgos Korfiatis
# Copyright 2013 GRNET S.A. All rights reserved.
2 dc9da5b9 Giorgos Korfiatis
#
3 dc9da5b9 Giorgos Korfiatis
# Redistribution and use in source and binary forms, with or
4 dc9da5b9 Giorgos Korfiatis
# without modification, are permitted provided that the following
5 dc9da5b9 Giorgos Korfiatis
# conditions are met:
6 dc9da5b9 Giorgos Korfiatis
#
7 dc9da5b9 Giorgos Korfiatis
#   1. Redistributions of source code must retain the above
8 dc9da5b9 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
9 dc9da5b9 Giorgos Korfiatis
#      disclaimer.
10 dc9da5b9 Giorgos Korfiatis
#
11 dc9da5b9 Giorgos Korfiatis
#   2. Redistributions in binary form must reproduce the above
12 dc9da5b9 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
13 dc9da5b9 Giorgos Korfiatis
#      disclaimer in the documentation and/or other materials
14 dc9da5b9 Giorgos Korfiatis
#      provided with the distribution.
15 dc9da5b9 Giorgos Korfiatis
#
16 dc9da5b9 Giorgos Korfiatis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 dc9da5b9 Giorgos Korfiatis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 dc9da5b9 Giorgos Korfiatis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 dc9da5b9 Giorgos Korfiatis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 dc9da5b9 Giorgos Korfiatis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 dc9da5b9 Giorgos Korfiatis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 dc9da5b9 Giorgos Korfiatis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 dc9da5b9 Giorgos Korfiatis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 dc9da5b9 Giorgos Korfiatis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 dc9da5b9 Giorgos Korfiatis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 dc9da5b9 Giorgos Korfiatis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 dc9da5b9 Giorgos Korfiatis
# POSSIBILITY OF SUCH DAMAGE.
28 dc9da5b9 Giorgos Korfiatis
#
29 dc9da5b9 Giorgos Korfiatis
# The views and conclusions contained in the software and
30 dc9da5b9 Giorgos Korfiatis
# documentation are those of the authors and should not be
31 dc9da5b9 Giorgos Korfiatis
# interpreted as representing official policies, either expressed
32 dc9da5b9 Giorgos Korfiatis
# or implied, of GRNET S.A.
33 dc9da5b9 Giorgos Korfiatis
34 aa27f246 Giorgos Korfiatis
from astakos.im.models import (
35 64a43a9a Giorgos Korfiatis
    Resource, AstakosUser, Service,
36 a53ec93b Giorgos Korfiatis
    Project, ProjectMembership, ProjectResourceQuota)
37 ec5e00aa Giorgos Korfiatis
import astakos.quotaholder_app.callpoint as qh
38 2e7924de Giorgos Korfiatis
from astakos.quotaholder_app.exception import NoCapacityError
39 ae16bcad Giorgos Korfiatis
from django.db.models import Q
40 a53ec93b Giorgos Korfiatis
from synnefo.util.keypath import set_path
41 dc9da5b9 Giorgos Korfiatis
42 dc9da5b9 Giorgos Korfiatis
43 a53ec93b Giorgos Korfiatis
PROJECT_TAG = "project:"
44 a53ec93b Giorgos Korfiatis
USER_TAG = "user:"
45 a53ec93b Giorgos Korfiatis
46 a53ec93b Giorgos Korfiatis
def project_ref(value):
47 a53ec93b Giorgos Korfiatis
    return  PROJECT_TAG + value
48 a53ec93b Giorgos Korfiatis
49 a53ec93b Giorgos Korfiatis
50 a53ec93b Giorgos Korfiatis
def get_project_ref(project):
51 a53ec93b Giorgos Korfiatis
    return project_ref(project.uuid)
52 a53ec93b Giorgos Korfiatis
53 a53ec93b Giorgos Korfiatis
54 a53ec93b Giorgos Korfiatis
def user_ref(value):
55 a53ec93b Giorgos Korfiatis
    return USER_TAG + value
56 a53ec93b Giorgos Korfiatis
57 a53ec93b Giorgos Korfiatis
58 a53ec93b Giorgos Korfiatis
def get_user_ref(user):
59 a53ec93b Giorgos Korfiatis
    return user_ref(user.uuid)
60 a53ec93b Giorgos Korfiatis
61 a53ec93b Giorgos Korfiatis
62 a53ec93b Giorgos Korfiatis
def from_holding(holding, is_project=False):
63 68b991bc Giorgos Korfiatis
    limit, usage_min, usage_max = holding
64 a53ec93b Giorgos Korfiatis
    prefix = 'project_' if is_project else ''
65 a53ec93b Giorgos Korfiatis
    body = {prefix+'limit':   limit,
66 a53ec93b Giorgos Korfiatis
            prefix+'usage':   usage_max,
67 a53ec93b Giorgos Korfiatis
            prefix+'pending': usage_max-usage_min,
68 dc9da5b9 Giorgos Korfiatis
            }
69 dc9da5b9 Giorgos Korfiatis
    return body
70 dc9da5b9 Giorgos Korfiatis
71 dc9da5b9 Giorgos Korfiatis
72 a53ec93b Giorgos Korfiatis
def get_user_counters(users, resources=None, sources=None, flt=None):
73 a53ec93b Giorgos Korfiatis
    holders = [get_user_ref(user) for user in users]
74 a53ec93b Giorgos Korfiatis
    return qh.get_quota(holders=holders,
75 a53ec93b Giorgos Korfiatis
                        resources=resources,
76 a53ec93b Giorgos Korfiatis
                        sources=sources,
77 a53ec93b Giorgos Korfiatis
                        flt=flt)
78 dc9da5b9 Giorgos Korfiatis
79 dc9da5b9 Giorgos Korfiatis
80 a53ec93b Giorgos Korfiatis
def get_project_counters(projects, resources=None, sources=None):
81 a53ec93b Giorgos Korfiatis
    holders = [get_project_ref(project) for project in projects]
82 a53ec93b Giorgos Korfiatis
    return qh.get_quota(holders=holders,
83 a53ec93b Giorgos Korfiatis
                        resources=resources,
84 a53ec93b Giorgos Korfiatis
                        sources=sources)
85 dc9da5b9 Giorgos Korfiatis
86 dc9da5b9 Giorgos Korfiatis
87 a53ec93b Giorgos Korfiatis
def strip_names(counters):
88 a53ec93b Giorgos Korfiatis
    stripped = {}
89 a53ec93b Giorgos Korfiatis
    for ((holder, source, resource), value) in counters.iteritems():
90 a53ec93b Giorgos Korfiatis
        prefix, sep, holder = holder.partition(":")
91 a53ec93b Giorgos Korfiatis
        assert prefix in ["user", "project"]
92 a53ec93b Giorgos Korfiatis
        if source is not None:
93 a53ec93b Giorgos Korfiatis
            prefix, sep, source = source.partition(":")
94 a53ec93b Giorgos Korfiatis
            assert prefix == "project"
95 a53ec93b Giorgos Korfiatis
        stripped[(holder, source, resource)] = value
96 a53ec93b Giorgos Korfiatis
    return stripped
97 dc9da5b9 Giorgos Korfiatis
98 dc9da5b9 Giorgos Korfiatis
99 a53ec93b Giorgos Korfiatis
def get_related_sources(counters):
100 a53ec93b Giorgos Korfiatis
    projects = set()
101 a53ec93b Giorgos Korfiatis
    for (holder, source, resource) in counters.iterkeys():
102 a53ec93b Giorgos Korfiatis
        projects.add(source)
103 a53ec93b Giorgos Korfiatis
    return list(projects)
104 dc9da5b9 Giorgos Korfiatis
105 dc9da5b9 Giorgos Korfiatis
106 a53ec93b Giorgos Korfiatis
def mk_quota_dict(users_counters, project_counters):
107 a53ec93b Giorgos Korfiatis
    quota = {}
108 a53ec93b Giorgos Korfiatis
    for (holder, source, resource), u_value in users_counters.iteritems():
109 a53ec93b Giorgos Korfiatis
        p_value = project_counters[(source, None, resource)]
110 a53ec93b Giorgos Korfiatis
        values_dict = from_holding(u_value)
111 a53ec93b Giorgos Korfiatis
        values_dict.update(from_holding(p_value, is_project=True))
112 a53ec93b Giorgos Korfiatis
        set_path(quota, [holder, source, resource], values_dict,
113 a53ec93b Giorgos Korfiatis
                 createpath=True)
114 a53ec93b Giorgos Korfiatis
    return quota
115 a53ec93b Giorgos Korfiatis
116 dc9da5b9 Giorgos Korfiatis
117 a53ec93b Giorgos Korfiatis
def get_users_quotas_counters(users, resources=None, sources=None, flt=None):
118 a53ec93b Giorgos Korfiatis
    user_counters = get_user_counters(users, resources, sources, flt=flt)
119 a53ec93b Giorgos Korfiatis
    projects = get_related_sources(user_counters)
120 a53ec93b Giorgos Korfiatis
    project_counters = qh.get_quota(holders=projects, resources=resources)
121 a53ec93b Giorgos Korfiatis
    return strip_names(user_counters), strip_names(project_counters)
122 dc9da5b9 Giorgos Korfiatis
123 a53ec93b Giorgos Korfiatis
124 a53ec93b Giorgos Korfiatis
def get_users_quotas(users, resources=None, sources=None, flt=None):
125 a53ec93b Giorgos Korfiatis
    u_c, p_c = get_users_quotas_counters(users, resources, sources, flt=flt)
126 a53ec93b Giorgos Korfiatis
    return mk_quota_dict(u_c, p_c)
127 dc9da5b9 Giorgos Korfiatis
128 dc9da5b9 Giorgos Korfiatis
129 dc9da5b9 Giorgos Korfiatis
def get_user_quotas(user, resources=None, sources=None):
130 dc9da5b9 Giorgos Korfiatis
    quotas = get_users_quotas([user], resources, sources)
131 1e361a6d Giorgos Korfiatis
    return quotas.get(user.uuid, {})
132 dc9da5b9 Giorgos Korfiatis
133 dc9da5b9 Giorgos Korfiatis
134 bea584e1 Giorgos Korfiatis
def service_get_quotas(component, users=None):
135 0e08e08e Giorgos Korfiatis
    name_values = Service.objects.filter(
136 0e08e08e Giorgos Korfiatis
        component=component).values_list('name')
137 0e08e08e Giorgos Korfiatis
    service_names = [t for (t,) in name_values]
138 0e08e08e Giorgos Korfiatis
    resources = Resource.objects.filter(service_origin__in=service_names)
139 bb005bc2 Giorgos Korfiatis
    resource_names = [r.name for r in resources]
140 a53ec93b Giorgos Korfiatis
    astakosusers = AstakosUser.objects.verified()
141 a53ec93b Giorgos Korfiatis
    if users is not None:
142 a53ec93b Giorgos Korfiatis
        astakosusers = astakosusers.filter(uuid__in=users)
143 a53ec93b Giorgos Korfiatis
    return get_users_quotas(astakosusers, resources=resource_names)
144 a53ec93b Giorgos Korfiatis
145 a53ec93b Giorgos Korfiatis
146 a53ec93b Giorgos Korfiatis
def mk_limits_dict(counters):
147 a53ec93b Giorgos Korfiatis
    quota = {}
148 a53ec93b Giorgos Korfiatis
    for key, (limit, _, _) in counters.iteritems():
149 a53ec93b Giorgos Korfiatis
        path = list(key)
150 a53ec93b Giorgos Korfiatis
        set_path(quota, path, limit, createpath=True)
151 a53ec93b Giorgos Korfiatis
    return quota
152 a53ec93b Giorgos Korfiatis
153 a53ec93b Giorgos Korfiatis
154 a53ec93b Giorgos Korfiatis
def mk_project_quota_dict(project_counters):
155 a53ec93b Giorgos Korfiatis
    quota = {}
156 a53ec93b Giorgos Korfiatis
    for (holder, _, resource), p_value in project_counters.iteritems():
157 a53ec93b Giorgos Korfiatis
        values_dict = from_holding(p_value, is_project=True)
158 a53ec93b Giorgos Korfiatis
        set_path(quota, [holder, resource], values_dict,
159 a53ec93b Giorgos Korfiatis
                 createpath=True)
160 a53ec93b Giorgos Korfiatis
    return quota
161 a53ec93b Giorgos Korfiatis
162 a53ec93b Giorgos Korfiatis
163 a53ec93b Giorgos Korfiatis
def get_projects_quota(projects, resources=None, sources=None):
164 a53ec93b Giorgos Korfiatis
    project_counters = get_project_counters(projects, resources, sources)
165 a53ec93b Giorgos Korfiatis
    return mk_project_quota_dict(strip_names(project_counters))
166 a53ec93b Giorgos Korfiatis
167 a53ec93b Giorgos Korfiatis
168 dccd7fa0 Giorgos Korfiatis
def service_get_project_quotas(component, projects=None):
169 dccd7fa0 Giorgos Korfiatis
    name_values = Service.objects.filter(
170 dccd7fa0 Giorgos Korfiatis
        component=component).values_list('name')
171 dccd7fa0 Giorgos Korfiatis
    service_names = [t for (t,) in name_values]
172 dccd7fa0 Giorgos Korfiatis
    resources = Resource.objects.filter(service_origin__in=service_names)
173 dccd7fa0 Giorgos Korfiatis
    resource_names = [r.name for r in resources]
174 dccd7fa0 Giorgos Korfiatis
    ps = Project.objects.initialized()
175 dccd7fa0 Giorgos Korfiatis
    if projects is not None:
176 dccd7fa0 Giorgos Korfiatis
        ps = ps.filter(uuid__in=projects)
177 dccd7fa0 Giorgos Korfiatis
    return get_projects_quota(ps, resources=resource_names)
178 dccd7fa0 Giorgos Korfiatis
179 dccd7fa0 Giorgos Korfiatis
180 a53ec93b Giorgos Korfiatis
def get_project_quota(project, resources=None, sources=None):
181 a53ec93b Giorgos Korfiatis
    quotas = get_projects_quota([project], resources, sources)
182 a53ec93b Giorgos Korfiatis
    return quotas.get(project.uuid, {})
183 a53ec93b Giorgos Korfiatis
184 a53ec93b Giorgos Korfiatis
185 a53ec93b Giorgos Korfiatis
def get_projects_quota_limits():
186 a53ec93b Giorgos Korfiatis
    project_counters = qh.get_quota(flt=Q(holder__startswith=PROJECT_TAG))
187 a53ec93b Giorgos Korfiatis
    user_counters = qh.get_quota(flt=Q(holder__startswith=USER_TAG))
188 a53ec93b Giorgos Korfiatis
    return mk_limits_dict(project_counters), mk_limits_dict(user_counters)
189 bb005bc2 Giorgos Korfiatis
190 bb005bc2 Giorgos Korfiatis
191 9b126f13 Giorgos Korfiatis
def _level_quota_dict(quotas):
192 9b126f13 Giorgos Korfiatis
    lst = []
193 9b126f13 Giorgos Korfiatis
    for holder, holder_quota in quotas.iteritems():
194 9b126f13 Giorgos Korfiatis
        for source, source_quota in holder_quota.iteritems():
195 9b126f13 Giorgos Korfiatis
            for resource, limit in source_quota.iteritems():
196 9b126f13 Giorgos Korfiatis
                key = (holder, source, resource)
197 9b126f13 Giorgos Korfiatis
                lst.append((key, limit))
198 9b126f13 Giorgos Korfiatis
    return lst
199 9b126f13 Giorgos Korfiatis
200 9b126f13 Giorgos Korfiatis
201 a53ec93b Giorgos Korfiatis
def set_quota(quotas, resource=None):
202 9b126f13 Giorgos Korfiatis
    q = _level_quota_dict(quotas)
203 548938f6 Giorgos Korfiatis
    qh.set_quota(q, resource=resource)
204 aa27f246 Giorgos Korfiatis
205 aa27f246 Giorgos Korfiatis
206 3c22bad0 Giorgos Korfiatis
PENDING_APP_RESOURCE = 'astakos.pending_app'
207 aa27f246 Giorgos Korfiatis
208 aa27f246 Giorgos Korfiatis
209 a53ec93b Giorgos Korfiatis
def mk_user_provision(user, source, resource, quantity):
210 a53ec93b Giorgos Korfiatis
    holder = user_ref(user)
211 a53ec93b Giorgos Korfiatis
    source = project_ref(source)
212 a53ec93b Giorgos Korfiatis
    return (holder, source, resource), quantity
213 a53ec93b Giorgos Korfiatis
214 a53ec93b Giorgos Korfiatis
215 a53ec93b Giorgos Korfiatis
def mk_project_provision(project, resource, quantity):
216 a53ec93b Giorgos Korfiatis
    holder = project_ref(project)
217 a53ec93b Giorgos Korfiatis
    return (holder, None, resource), quantity
218 a53ec93b Giorgos Korfiatis
219 a53ec93b Giorgos Korfiatis
220 a53ec93b Giorgos Korfiatis
def _mk_provisions(holder, source, resource, quantity):
221 a53ec93b Giorgos Korfiatis
    return [((holder, source, resource), quantity),
222 a53ec93b Giorgos Korfiatis
            ((source, None, resource), quantity)]
223 a53ec93b Giorgos Korfiatis
224 a53ec93b Giorgos Korfiatis
225 a53ec93b Giorgos Korfiatis
def register_pending_apps(user, project, quantity, force=False):
226 a53ec93b Giorgos Korfiatis
    provisions = _mk_provisions(get_user_ref(user), get_project_ref(project),
227 a53ec93b Giorgos Korfiatis
                                PENDING_APP_RESOURCE, quantity)
228 9e3af524 Giorgos Korfiatis
    try:
229 9e3af524 Giorgos Korfiatis
        s = qh.issue_commission(clientkey='astakos',
230 9e3af524 Giorgos Korfiatis
                                force=force,
231 a53ec93b Giorgos Korfiatis
                                provisions=provisions)
232 9e3af524 Giorgos Korfiatis
    except NoCapacityError as e:
233 9e3af524 Giorgos Korfiatis
        limit = e.data['limit']
234 9e3af524 Giorgos Korfiatis
        return False, limit
235 3c22bad0 Giorgos Korfiatis
    qh.resolve_pending_commission('astakos', s)
236 9e3af524 Giorgos Korfiatis
    return True, None
237 9770ba6c Giorgos Korfiatis
238 9770ba6c Giorgos Korfiatis
239 3c22bad0 Giorgos Korfiatis
def get_pending_app_quota(user):
240 3c22bad0 Giorgos Korfiatis
    quota = get_user_quotas(user)
241 a53ec93b Giorgos Korfiatis
    source = user.base_project.uuid
242 a53ec93b Giorgos Korfiatis
    return quota[source][PENDING_APP_RESOURCE]
243 3c22bad0 Giorgos Korfiatis
244 3c22bad0 Giorgos Korfiatis
245 46b6a8b4 Giorgos Korfiatis
def _partition_by(f, l):
246 46b6a8b4 Giorgos Korfiatis
    d = {}
247 46b6a8b4 Giorgos Korfiatis
    for x in l:
248 46b6a8b4 Giorgos Korfiatis
        group = f(x)
249 46b6a8b4 Giorgos Korfiatis
        group_l = d.get(group, [])
250 46b6a8b4 Giorgos Korfiatis
        group_l.append(x)
251 46b6a8b4 Giorgos Korfiatis
        d[group] = group_l
252 46b6a8b4 Giorgos Korfiatis
    return d
253 46b6a8b4 Giorgos Korfiatis
254 46b6a8b4 Giorgos Korfiatis
255 a53ec93b Giorgos Korfiatis
def astakos_project_quotas(projects, resource=None):
256 362dadaa Giorgos Korfiatis
    objs = ProjectResourceQuota.objects.select_related()
257 a53ec93b Giorgos Korfiatis
    flt = Q(resource__name=resource) if resource is not None else Q()
258 a53ec93b Giorgos Korfiatis
    grants = objs.filter(project__in=projects).filter(flt)
259 a53ec93b Giorgos Korfiatis
    grants_d = _partition_by(lambda g: g.project_id, grants)
260 a53ec93b Giorgos Korfiatis
261 a53ec93b Giorgos Korfiatis
    objs = ProjectMembership.objects
262 a53ec93b Giorgos Korfiatis
    memberships = objs.initialized(projects).select_related(
263 a53ec93b Giorgos Korfiatis
        "person", "project")
264 a53ec93b Giorgos Korfiatis
    memberships_d = _partition_by(lambda m: m.project_id, memberships)
265 a53ec93b Giorgos Korfiatis
266 a53ec93b Giorgos Korfiatis
    user_quota = {}
267 a53ec93b Giorgos Korfiatis
    project_quota = {}
268 a53ec93b Giorgos Korfiatis
269 a53ec93b Giorgos Korfiatis
    for project in projects:
270 a53ec93b Giorgos Korfiatis
        pr_ref = get_project_ref(project)
271 a53ec93b Giorgos Korfiatis
        state = project.state
272 a53ec93b Giorgos Korfiatis
        if state not in Project.INITIALIZED_STATES:
273 a53ec93b Giorgos Korfiatis
            continue
274 a53ec93b Giorgos Korfiatis
275 a53ec93b Giorgos Korfiatis
        project_grants = grants_d.get(project.id, [])
276 a53ec93b Giorgos Korfiatis
        project_memberships = memberships_d.get(project.id, [])
277 a53ec93b Giorgos Korfiatis
        for grant in project_grants:
278 a53ec93b Giorgos Korfiatis
            resource = grant.resource.name
279 a53ec93b Giorgos Korfiatis
            path = [pr_ref, None, resource]
280 a53ec93b Giorgos Korfiatis
            val = grant.project_capacity if state == Project.NORMAL else 0
281 a53ec93b Giorgos Korfiatis
            set_path(project_quota, path, val, createpath=True)
282 a53ec93b Giorgos Korfiatis
            for membership in project_memberships:
283 a53ec93b Giorgos Korfiatis
                u_ref = get_user_ref(membership.person)
284 a53ec93b Giorgos Korfiatis
                path = [u_ref, pr_ref, resource]
285 a53ec93b Giorgos Korfiatis
                val = grant.member_capacity if membership.is_active() else 0
286 a53ec93b Giorgos Korfiatis
                set_path(user_quota, path, val, createpath=True)
287 a53ec93b Giorgos Korfiatis
288 a53ec93b Giorgos Korfiatis
    return project_quota, user_quota
289 a53ec93b Giorgos Korfiatis
290 a53ec93b Giorgos Korfiatis
291 a53ec93b Giorgos Korfiatis
def list_user_quotas(users, qhflt=None):
292 5a0f9d6c Giorgos Korfiatis
    qh_quotas = get_users_quotas(users, flt=qhflt)
293 a53ec93b Giorgos Korfiatis
    return qh_quotas
294 3c22bad0 Giorgos Korfiatis
295 3c22bad0 Giorgos Korfiatis
296 a53ec93b Giorgos Korfiatis
def qh_sync_projects(projects, resource=None):
297 a53ec93b Giorgos Korfiatis
    p_quota, u_quota = astakos_project_quotas(projects, resource=resource)
298 a53ec93b Giorgos Korfiatis
    p_quota.update(u_quota)
299 a53ec93b Giorgos Korfiatis
    set_quota(p_quota, resource=resource)
300 3c22bad0 Giorgos Korfiatis
301 3c22bad0 Giorgos Korfiatis
302 a53ec93b Giorgos Korfiatis
def qh_sync_project(project):
303 a53ec93b Giorgos Korfiatis
    qh_sync_projects([project])
304 3c22bad0 Giorgos Korfiatis
305 e336910f Giorgos Korfiatis
306 a53ec93b Giorgos Korfiatis
def membership_quota(membership):
307 a53ec93b Giorgos Korfiatis
    project = membership.project
308 a53ec93b Giorgos Korfiatis
    pr_ref = get_project_ref(project)
309 a53ec93b Giorgos Korfiatis
    u_ref = get_user_ref(membership.person)
310 a53ec93b Giorgos Korfiatis
    objs = ProjectResourceQuota.objects.select_related()
311 a53ec93b Giorgos Korfiatis
    grants = objs.filter(project=project)
312 a53ec93b Giorgos Korfiatis
    user_quota = {}
313 a53ec93b Giorgos Korfiatis
    is_active = membership.is_active()
314 a53ec93b Giorgos Korfiatis
    for grant in grants:
315 a53ec93b Giorgos Korfiatis
        resource = grant.resource.name
316 a53ec93b Giorgos Korfiatis
        path = [u_ref, pr_ref, resource]
317 a53ec93b Giorgos Korfiatis
        value = grant.member_capacity if is_active else 0
318 a53ec93b Giorgos Korfiatis
        set_path(user_quota, path, value, createpath=True)
319 a53ec93b Giorgos Korfiatis
    return user_quota
320 a53ec93b Giorgos Korfiatis
321 a53ec93b Giorgos Korfiatis
322 a53ec93b Giorgos Korfiatis
def qh_sync_membership(membership):
323 a53ec93b Giorgos Korfiatis
    quota = membership_quota(membership)
324 a53ec93b Giorgos Korfiatis
    set_quota(quota)
325 a53ec93b Giorgos Korfiatis
326 a53ec93b Giorgos Korfiatis
327 362dadaa Giorgos Korfiatis
def pick_limit_scheme(project, resource):
328 362dadaa Giorgos Korfiatis
    return resource.uplimit if project.is_base else resource.project_default
329 362dadaa Giorgos Korfiatis
330 362dadaa Giorgos Korfiatis
331 2e46be99 Giorgos Korfiatis
def qh_sync_new_resource(resource):
332 a53ec93b Giorgos Korfiatis
    projects = Project.objects.filter(state__in=Project.INITIALIZED_STATES).\
333 a53ec93b Giorgos Korfiatis
        select_for_update()
334 9747707e Giorgos Korfiatis
335 f72ba65d Giorgos Korfiatis
    entries = []
336 a53ec93b Giorgos Korfiatis
    for project in projects:
337 a53ec93b Giorgos Korfiatis
        limit = pick_limit_scheme(project, resource)
338 f72ba65d Giorgos Korfiatis
        entries.append(
339 a53ec93b Giorgos Korfiatis
            ProjectResourceQuota(
340 a53ec93b Giorgos Korfiatis
                project=project,
341 a53ec93b Giorgos Korfiatis
                resource=resource,
342 a53ec93b Giorgos Korfiatis
                project_capacity=limit,
343 a53ec93b Giorgos Korfiatis
                member_capacity=limit))
344 a53ec93b Giorgos Korfiatis
    ProjectResourceQuota.objects.bulk_create(entries)
345 a53ec93b Giorgos Korfiatis
    qh_sync_projects(projects, resource=resource.name)