Skip to content

Commit 7b6e2ce

Browse files
authored
Merge pull request #38 from infn-datacloud/fix-quota-moltiplication
Fix wrong duplication of usage quotas
2 parents a58a1e9 + 57dd6f6 commit 7b6e2ce

File tree

5 files changed

+129
-41
lines changed

5 files changed

+129
-41
lines changed

fed_reg/service/crud.py

Lines changed: 124 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,20 @@
6363

6464

6565
def split_quota(quotas: list[Any]) -> Tuple[Dict[str, Any], Dict[str, Any]]:
66-
"""Split quotas in total and per-users."""
66+
"""Split quotas in usage, per-user, per-project."""
67+
db_items_usage = {
68+
db_item.project.single().uuid: db_item
69+
for db_item in filter(lambda x: x.usage, quotas)
70+
}
6771
db_items_per_user = {
6872
db_item.project.single().uuid: db_item
69-
for db_item in filter(lambda x: x.per_user, quotas)
73+
for db_item in filter(lambda x: x.per_user and not x.usage, quotas)
7074
}
71-
db_items_total = {
75+
db_items_per_project = {
7276
db_item.project.single().uuid: db_item
73-
for db_item in filter(lambda x: not x.per_user, quotas)
77+
for db_item in filter(lambda x: not x.per_user and not x.usage, quotas)
7478
}
75-
return (db_items_per_user, db_items_total)
79+
return (db_items_usage, db_items_per_user, db_items_per_project)
7680

7781

7882
class CRUDBlockStorageService(
@@ -150,7 +154,7 @@ def update(
150154
update_data = super().update(db_obj=db_obj, obj_in=obj_in, force=force)
151155
return db_obj if edit else update_data
152156

153-
def __update_quotas(
157+
def __update_quotas( # noqa: C901
154158
self,
155159
*,
156160
db_obj: BlockStorageService,
@@ -162,17 +166,37 @@ def __update_quotas(
162166
Connect new quotas not already connect, leave untouched already linked ones and
163167
delete old ones no more connected to the service.
164168
165-
Split quotas in per_user and total. For each one of them, check the linked
166-
project. If the project already has a quota of that type, update that quota with
167-
the new received values.
169+
Split quotas in usage, per_user and per_project. For each one of them, check the
170+
linked project. If the project already has a quota of that type, update that
171+
quota with the new received values.
168172
"""
169173
edit = False
170174

171-
db_items_per_user, db_items_total = split_quota(db_obj.quotas)
175+
db_items_usage, db_items_per_user, db_items_per_project = split_quota(
176+
db_obj.quotas
177+
)
172178
db_projects = {db_item.uuid: db_item for db_item in provider_projects}
173179

174180
for item in obj_in.quotas:
175-
if item.per_user:
181+
if item.usage:
182+
db_item = db_items_usage.pop(item.project, None)
183+
if not db_item:
184+
block_storage_quota_mng.create(
185+
obj_in=item,
186+
service=db_obj,
187+
project=db_projects.get(item.project),
188+
)
189+
edit = True
190+
else:
191+
updated_data = block_storage_quota_mng.update(
192+
db_obj=db_item,
193+
obj_in=item,
194+
projects=provider_projects,
195+
force=True,
196+
)
197+
if not edit and updated_data is not None:
198+
edit = True
199+
elif item.per_user:
176200
db_item = db_items_per_user.pop(item.project, None)
177201
if not db_item:
178202
block_storage_quota_mng.create(
@@ -191,7 +215,7 @@ def __update_quotas(
191215
if not edit and updated_data is not None:
192216
edit = True
193217
else:
194-
db_item = db_items_total.pop(item.project, None)
218+
db_item = db_items_per_project.pop(item.project, None)
195219
if not db_item:
196220
block_storage_quota_mng.create(
197221
obj_in=item,
@@ -209,10 +233,13 @@ def __update_quotas(
209233
if not edit and updated_data is not None:
210234
edit = True
211235

236+
for db_item in db_items_usage.values():
237+
block_storage_quota_mng.remove(db_obj=db_item)
238+
edit = True
212239
for db_item in db_items_per_user.values():
213240
block_storage_quota_mng.remove(db_obj=db_item)
214241
edit = True
215-
for db_item in db_items_total.values():
242+
for db_item in db_items_per_project.values():
216243
block_storage_quota_mng.remove(db_obj=db_item)
217244
edit = True
218245

@@ -388,7 +415,7 @@ def __update_images(
388415
edit = True
389416
return edit
390417

391-
def __update_quotas(
418+
def __update_quotas( # noqa: C901
392419
self,
393420
*,
394421
db_obj: ComputeService,
@@ -406,11 +433,31 @@ def __update_quotas(
406433
"""
407434
edit = False
408435

409-
db_items_per_user, db_items_total = split_quota(db_obj.quotas)
436+
db_items_usage, db_items_per_user, db_items_per_project = split_quota(
437+
db_obj.quotas
438+
)
410439
db_projects = {db_item.uuid: db_item for db_item in provider_projects}
411440

412441
for item in obj_in.quotas:
413-
if item.per_user:
442+
if item.usage:
443+
db_item = db_items_usage.pop(item.project, None)
444+
if not db_item:
445+
block_storage_quota_mng.create(
446+
obj_in=item,
447+
service=db_obj,
448+
project=db_projects.get(item.project),
449+
)
450+
edit = True
451+
else:
452+
updated_data = block_storage_quota_mng.update(
453+
db_obj=db_item,
454+
obj_in=item,
455+
projects=provider_projects,
456+
force=True,
457+
)
458+
if not edit and updated_data is not None:
459+
edit = True
460+
elif item.per_user:
414461
db_item = db_items_per_user.pop(item.project, None)
415462
if not db_item:
416463
compute_quota_mng.create(
@@ -429,7 +476,7 @@ def __update_quotas(
429476
if not edit and updated_data is not None:
430477
edit = True
431478
else:
432-
db_item = db_items_total.pop(item.project, None)
479+
db_item = db_items_per_project.pop(item.project, None)
433480
if not db_item:
434481
compute_quota_mng.create(
435482
obj_in=item,
@@ -447,10 +494,13 @@ def __update_quotas(
447494
if not edit and updated_data is not None:
448495
edit = True
449496

497+
for db_item in db_items_usage.values():
498+
block_storage_quota_mng.remove(db_obj=db_item)
499+
edit = True
450500
for db_item in db_items_per_user.values():
451501
compute_quota_mng.remove(db_obj=db_item)
452502
edit = True
453-
for db_item in db_items_total.values():
503+
for db_item in db_items_per_project.values():
454504
compute_quota_mng.remove(db_obj=db_item)
455505
edit = True
456506

@@ -611,7 +661,7 @@ def __update_networks(
611661
edit = True
612662
return edit
613663

614-
def __update_quotas(
664+
def __update_quotas( # noqa: C901
615665
self,
616666
*,
617667
db_obj: NetworkService,
@@ -629,11 +679,31 @@ def __update_quotas(
629679
"""
630680
edit = False
631681

632-
db_items_per_user, db_items_total = split_quota(db_obj.quotas)
682+
db_items_usage, db_items_per_user, db_items_per_project = split_quota(
683+
db_obj.quotas
684+
)
633685
db_projects = {db_item.uuid: db_item for db_item in provider_projects}
634686

635687
for item in obj_in.quotas:
636-
if item.per_user:
688+
if item.usage:
689+
db_item = db_items_usage.pop(item.project, None)
690+
if not db_item:
691+
block_storage_quota_mng.create(
692+
obj_in=item,
693+
service=db_obj,
694+
project=db_projects.get(item.project),
695+
)
696+
edit = True
697+
else:
698+
updated_data = block_storage_quota_mng.update(
699+
db_obj=db_item,
700+
obj_in=item,
701+
projects=provider_projects,
702+
force=True,
703+
)
704+
if not edit and updated_data is not None:
705+
edit = True
706+
elif item.per_user:
637707
db_item = db_items_per_user.pop(item.project, None)
638708
if not db_item:
639709
network_quota_mng.create(
@@ -652,7 +722,7 @@ def __update_quotas(
652722
if not edit and updated_data is not None:
653723
edit = True
654724
else:
655-
db_item = db_items_total.pop(item.project, None)
725+
db_item = db_items_per_project.pop(item.project, None)
656726
if not db_item:
657727
network_quota_mng.create(
658728
obj_in=item,
@@ -670,10 +740,13 @@ def __update_quotas(
670740
if not edit and updated_data is not None:
671741
edit = True
672742

743+
for db_item in db_items_usage.values():
744+
block_storage_quota_mng.remove(db_obj=db_item)
745+
edit = True
673746
for db_item in db_items_per_user.values():
674747
network_quota_mng.remove(db_obj=db_item)
675748
edit = True
676-
for db_item in db_items_total.values():
749+
for db_item in db_items_per_project.values():
677750
network_quota_mng.remove(db_obj=db_item)
678751
edit = True
679752

@@ -755,7 +828,7 @@ def update(
755828
update_data = super().update(db_obj=db_obj, obj_in=obj_in, force=force)
756829
return db_obj if edit else update_data
757830

758-
def __update_quotas(
831+
def __update_quotas( # noqa: C901
759832
self,
760833
*,
761834
db_obj: ObjectStoreService,
@@ -773,11 +846,31 @@ def __update_quotas(
773846
"""
774847
edit = False
775848

776-
db_items_per_user, db_items_total = split_quota(db_obj.quotas)
849+
db_items_usage, db_items_per_user, db_items_per_project = split_quota(
850+
db_obj.quotas
851+
)
777852
db_projects = {db_item.uuid: db_item for db_item in provider_projects}
778853

779854
for item in obj_in.quotas:
780-
if item.per_user:
855+
if item.usage:
856+
db_item = db_items_usage.pop(item.project, None)
857+
if not db_item:
858+
block_storage_quota_mng.create(
859+
obj_in=item,
860+
service=db_obj,
861+
project=db_projects.get(item.project),
862+
)
863+
edit = True
864+
else:
865+
updated_data = block_storage_quota_mng.update(
866+
db_obj=db_item,
867+
obj_in=item,
868+
projects=provider_projects,
869+
force=True,
870+
)
871+
if not edit and updated_data is not None:
872+
edit = True
873+
elif item.per_user:
781874
db_item = db_items_per_user.pop(item.project, None)
782875
if not db_item:
783876
object_store_quota_mng.create(
@@ -796,7 +889,7 @@ def __update_quotas(
796889
if not edit and updated_data is not None:
797890
edit = True
798891
else:
799-
db_item = db_items_total.pop(item.project, None)
892+
db_item = db_items_per_project.pop(item.project, None)
800893
if not db_item:
801894
object_store_quota_mng.create(
802895
obj_in=item,
@@ -814,10 +907,13 @@ def __update_quotas(
814907
if not edit and updated_data is not None:
815908
edit = True
816909

910+
for db_item in db_items_usage.values():
911+
block_storage_quota_mng.remove(db_obj=db_item)
912+
edit = True
817913
for db_item in db_items_per_user.values():
818914
object_store_quota_mng.remove(db_obj=db_item)
819915
edit = True
820-
for db_item in db_items_total.values():
916+
for db_item in db_items_per_project.values():
821917
object_store_quota_mng.remove(db_obj=db_item)
822918
edit = True
823919

tests/models/test_quota_model.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,10 @@ def test_linked_object_store_service(
203203
assert object_store_quota_model.service.name
204204
assert object_store_quota_model.service.source
205205
assert isinstance(object_store_quota_model.service.source, Quota)
206-
assert (
207-
object_store_quota_model.service.source.uid == object_store_quota_model.uid
208-
)
206+
assert object_store_quota_model.service.source.uid == object_store_quota_model.uid
209207
assert object_store_quota_model.service.definition
210208
assert (
211-
object_store_quota_model.service.definition["node_class"]
212-
== ObjectStoreService
209+
object_store_quota_model.service.definition["node_class"] == ObjectStoreService
213210
)
214211

215212
r = object_store_quota_model.service.connect(object_store_service_model)

tests/models/test_service_model.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,11 @@ def test_linked_object_store_quota(
313313
assert object_store_service_model.quotas.source
314314
assert isinstance(object_store_service_model.quotas.source, ObjectStoreService)
315315
assert (
316-
object_store_service_model.quotas.source.uid
317-
== object_store_service_model.uid
316+
object_store_service_model.quotas.source.uid == object_store_service_model.uid
318317
)
319318
assert object_store_service_model.quotas.definition
320319
assert (
321-
object_store_service_model.quotas.definition["node_class"]
322-
== ObjectStoreQuota
320+
object_store_service_model.quotas.definition["node_class"] == ObjectStoreQuota
323321
)
324322

325323
r = object_store_service_model.quotas.connect(object_store_quota_model)

tests/schemas/test_block_storage_quota_invalid_schema_cases.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,3 @@ def case_integer(self, attr: str) -> tuple[str, int]:
1414
@parametrize(value=(i for i in QuotaType if i != QuotaType.BLOCK_STORAGE))
1515
def case_type(self, value: QuotaType) -> tuple[Literal["type"], QuotaType]:
1616
return "type", value
17-

tests/schemas/test_object_storage_quota_schema.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ def test_read_public(
3838

3939

4040
@parametrize_with_cases("key, value")
41-
def test_read(
42-
object_store_quota_model: ObjectStoreQuota, key: str, value: Any
43-
) -> None:
41+
def test_read(object_store_quota_model: ObjectStoreQuota, key: str, value: Any) -> None:
4442
if key:
4543
object_store_quota_model.__setattr__(key, value)
4644
item = ObjectStoreQuotaRead.from_orm(object_store_quota_model)

0 commit comments

Comments
 (0)