Revision aa27f246 snf-astakos-app/astakos/im/quotas.py
b/snf-astakos-app/astakos/im/quotas.py | ||
---|---|---|
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 |
from astakos.im.models import ( |
|
35 |
Resource, AstakosUserQuota, AstakosUser, |
|
36 |
Project, ProjectMembership, ProjectResourceGrant, ProjectApplication) |
|
34 | 37 |
from astakos.quotaholder.callpoint import QuotaholderDjangoDBCallpoint |
35 | 38 |
|
36 | 39 |
qh = QuotaholderDjangoDBCallpoint() |
... | ... | |
94 | 97 |
|
95 | 98 |
def set_user_quota(quotas): |
96 | 99 |
qh.set_holder_quota(quotas) |
100 |
|
|
101 |
|
|
102 |
def get_default_quota(): |
|
103 |
_DEFAULT_QUOTA = {} |
|
104 |
resources = Resource.objects.select_related('service').all() |
|
105 |
for resource in resources: |
|
106 |
capacity = resource.uplimit |
|
107 |
_DEFAULT_QUOTA[resource.full_name()] = capacity |
|
108 |
|
|
109 |
return _DEFAULT_QUOTA |
|
110 |
|
|
111 |
|
|
112 |
SYSTEM = 'system' |
|
113 |
|
|
114 |
|
|
115 |
def initial_quotas(users): |
|
116 |
initial = {} |
|
117 |
default_quotas = get_default_quota() |
|
118 |
|
|
119 |
for user in users: |
|
120 |
uuid = user.uuid |
|
121 |
source_quota = {SYSTEM: dict(default_quotas)} |
|
122 |
initial[uuid] = source_quota |
|
123 |
|
|
124 |
objs = AstakosUserQuota.objects.select_related() |
|
125 |
orig_quotas = objs.filter(user__in=users) |
|
126 |
for user_quota in orig_quotas: |
|
127 |
uuid = user_quota.user.uuid |
|
128 |
user_init = initial.get(uuid, {}) |
|
129 |
resource = user_quota.resource.full_name() |
|
130 |
user_init[resource] = user_quota.capacity |
|
131 |
initial[uuid] = user_init |
|
132 |
|
|
133 |
return initial |
|
134 |
|
|
135 |
|
|
136 |
def get_grant_source(grant): |
|
137 |
return SYSTEM |
|
138 |
|
|
139 |
|
|
140 |
def users_quotas(users, initial=None): |
|
141 |
if initial is None: |
|
142 |
quotas = initial_quotas(users) |
|
143 |
else: |
|
144 |
quotas = copy.deepcopy(initial) |
|
145 |
|
|
146 |
ACTUALLY_ACCEPTED = ProjectMembership.ACTUALLY_ACCEPTED |
|
147 |
objs = ProjectMembership.objects.select_related('project', 'person') |
|
148 |
memberships = objs.filter(person__in=users, |
|
149 |
state__in=ACTUALLY_ACCEPTED, |
|
150 |
project__state=Project.APPROVED) |
|
151 |
|
|
152 |
project_ids = set(m.project_id for m in memberships) |
|
153 |
objs = ProjectApplication.objects.select_related('project') |
|
154 |
apps = objs.filter(project__in=project_ids) |
|
155 |
|
|
156 |
project_dict = {} |
|
157 |
for app in apps: |
|
158 |
project_dict[app.project] = app |
|
159 |
|
|
160 |
objs = ProjectResourceGrant.objects.select_related() |
|
161 |
grants = objs.filter(project_application__in=apps) |
|
162 |
|
|
163 |
for membership in memberships: |
|
164 |
uuid = membership.person.uuid |
|
165 |
userquotas = quotas.get(uuid, {}) |
|
166 |
|
|
167 |
application = project_dict[membership.project] |
|
168 |
|
|
169 |
for grant in grants: |
|
170 |
if grant.project_application_id != application.id: |
|
171 |
continue |
|
172 |
|
|
173 |
source = get_grant_source(grant) |
|
174 |
source_quotas = userquotas.get(source, {}) |
|
175 |
|
|
176 |
resource = grant.resource.full_name() |
|
177 |
prev = source_quotas.get(resource, 0) |
|
178 |
new = prev + grant.member_capacity |
|
179 |
source_quotas[resource] = new |
|
180 |
userquotas[source] = source_quotas |
|
181 |
quotas[uuid] = userquotas |
|
182 |
|
|
183 |
return quotas |
|
184 |
|
|
185 |
|
|
186 |
def user_quotas(user): |
|
187 |
quotas = users_quotas([user]) |
|
188 |
try: |
|
189 |
return quotas[user.uuid] |
|
190 |
except KeyError: |
|
191 |
raise ValueError("could not compute quotas") |
|
192 |
|
|
193 |
|
|
194 |
def sync_users(users, sync=True): |
|
195 |
def _sync_users(users, sync): |
|
196 |
|
|
197 |
info = {} |
|
198 |
for user in users: |
|
199 |
info[user.uuid] = user.email |
|
200 |
|
|
201 |
qh_quotas, qh_limits = get_users_quotas_and_limits(users) |
|
202 |
astakos_initial = initial_quotas(users) |
|
203 |
astakos_quotas = users_quotas(users) |
|
204 |
|
|
205 |
diff_quotas = {} |
|
206 |
for holder, local in astakos_quotas.iteritems(): |
|
207 |
registered = qh_limits.get(holder, None) |
|
208 |
if local != registered: |
|
209 |
diff_quotas[holder] = dict(local) |
|
210 |
|
|
211 |
if sync: |
|
212 |
r = set_user_quota(diff_quotas) |
|
213 |
|
|
214 |
return (qh_limits, qh_quotas, |
|
215 |
astakos_initial, diff_quotas, info) |
|
216 |
|
|
217 |
return _sync_users(users, sync) |
|
218 |
|
|
219 |
|
|
220 |
def sync_all_users(sync=True): |
|
221 |
users = AstakosUser.objects.verified() |
|
222 |
return sync_users(users, sync) |
Also available in: Unified diff