Skip to content

Commit 6e0a05d

Browse files
authored
fix: quota set to 0 and quota limit bad calc (#39)
2 parents d1dea72 + e18a665 commit 6e0a05d

5 files changed

Lines changed: 23 additions & 19 deletions

File tree

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ Makefile
1515
adminrc
1616
README.md
1717
.headscale
18+
.sass-cache/

fob_api/config.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ def parse_bool(value: str) -> bool:
66
:param value: The value to parse
77
:return: The boolean value or None if the value is not recognized
88
"""
9-
if not value:
10-
return None
119
list_of_true = ["true", "yes", "1"]
1210
list_of_false = ["false", "no", "0"]
1311
if value.lower() in list_of_true:
1412
return True
1513
if value.lower() in list_of_false:
1614
return False
15+
raise ValueError(f"Value {value} is not recognized as a boolean use one of {list_of_true + list_of_false}")
1716

1817
class SingletonMeta(type):
1918

fob_api/routes/openstack.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def remove_user_from_project(
242242
# try to sync quotas with openstack without user quotas if it fails rollback quotas
243243
try:
244244
openstack_tasks.sync_project_quota(os_project)
245-
except (nova_exceptions.ClientException, cinder_exceptions.ClientException) as e:
245+
except (nova_exceptions.ClientException, cinder_exceptions.ClientException):
246246
# rollback quotas when quota sync fails (when quota is lower than current usage)
247247
for project_quota in project_quotas:
248248
session.refresh(project_quota)

fob_api/routes/quota.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def calculate_user_quota(user: db_models.User) -> List[api_models.AdjustUserQuot
3636
user_max_quota_dict = {k: 0 for k in db_models.QuotaType}
3737
for q in session.exec(select(db_models.UserQuota).where(db_models.UserQuota.user_id == user.id)).all():
3838
user_max_quota_dict[db_models.QuotaType.from_str(q.type)] += q.quantity
39-
39+
4040
return [api_models.AdjustUserQuota(
4141
username=user.username,
4242
type=k,
@@ -49,7 +49,7 @@ def calculate_project_quota(project: db_models.Project) -> List[api_models.Adjus
4949
project_max_quota_dict = {k: 0 for k in db_models.QuotaType}
5050
for q in session.exec(select(db_models.UserQuotaShare).where(db_models.UserQuotaShare.project_id == project.id)).all():
5151
project_max_quota_dict[db_models.QuotaType.from_str(q.type)] += q.quantity
52-
52+
5353
return [api_models.AdjustProjectQuota(
5454
username="",
5555
project_name=project.name,
@@ -82,7 +82,7 @@ def get_user_left_quota_by_type(user: db_models.User, quota_type: db_models.Quot
8282
user_quota_own = 0
8383
for q in session.exec(select(db_models.UserQuota).where(db_models.UserQuota.user_id == user.id).where(db_models.UserQuota.type == quota_type)).all():
8484
user_quota_own += q.quantity
85-
85+
8686
user_quota_used = 0
8787
for q in session.exec(select(db_models.UserQuotaShare).where(db_models.UserQuotaShare.user_id == user.id).where(db_models.UserQuotaShare.type == quota_type)).all():
8888
user_quota_used += q.quantity
@@ -188,11 +188,6 @@ def set_quota_to_project(
188188
if not project_membership and project_find.owner_id != user_find.id:
189189
raise HTTPException(status_code=400, detail="User not in project")
190190

191-
# check if user has enough quota to share
192-
if get_user_left_quota_by_type(user_find, db_models.QuotaType.from_str(create_quota.type)) < create_quota.quantity:
193-
raise HTTPException(status_code=400, detail="User do not have enough quota to share")
194-
195-
# check if user has already shared quota
196191
quota = session.exec(
197192
select(db_models.UserQuotaShare)
198193
.where(
@@ -202,6 +197,14 @@ def set_quota_to_project(
202197
)
203198
).first()
204199
previous_quantity = 0
200+
if quota:
201+
previous_quantity = quota.quantity
202+
203+
# check if user has enough quota to share
204+
if get_user_left_quota_by_type(user_find, db_models.QuotaType.from_str(create_quota.type)) + previous_quantity < create_quota.quantity:
205+
raise HTTPException(status_code=400, detail="User do not have enough quota to share")
206+
207+
# check if user has already shared quota
205208
if quota:
206209
previous_quantity = quota.quantity
207210
quota.quantity = create_quota.quantity
@@ -215,10 +218,12 @@ def set_quota_to_project(
215218
type=create_quota.type
216219
)
217220
session.add(quota)
221+
if create_quota.quantity == 0:
222+
session.delete(quota)
218223
session.commit()
219224
try:
220225
sync_project_quota(project_find)
221-
except (nova_exceptions.ClientException, cinder_exceptions.ClientException) as e:
226+
except (nova_exceptions.ClientException, cinder_exceptions.ClientException):
222227
session.refresh(quota)
223228
quota.quantity = previous_quantity
224229
session.commit()
@@ -254,7 +259,7 @@ def show_project_adjustements(
254259
raise HTTPException(status_code=400, detail="Project not found")
255260
if not user.is_admin and not session.exec(select(db_models.ProjectUserMembership).where(db_models.ProjectUserMembership.project_id == project_find.id, db_models.ProjectUserMembership.user_id == user.id)).first() and project_find.owner_id != user.id:
256261
raise HTTPException(status_code=403, detail="Not allowed to see Adjustements for this project")
257-
262+
258263
shared_quotas = []
259264
for q in session.exec(select(db_models.UserQuotaShare).where(db_models.UserQuotaShare.project_id == project_find.id)).all():
260265
user = session.exec(select(db_models.User).where(db_models.User.id == q.user_id)).first()

fob_api/serializer.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@
22
from pydantic import BaseModel
33
from fob_api.models import api as api_models
44

5-
class PydanticSerializer(JSONEncoder):
5+
class PydanticSerializer(JSONEncoder):
66
def default(self, obj):
77
if isinstance(obj, BaseModel):
88
return obj.model_dump() | {'__type__': type(obj).__name__}
99
else:
1010
return JSONEncoder.default(self, obj)
1111

1212
def pydantic_decoder(obj):
13-
if '__type__' in obj:
14-
if obj['__type__'] in dir(api_models):
15-
cls = getattr(api_models, obj['__type__'])
16-
return cls.parse_obj(obj)
13+
if '__type__' in obj and obj['__type__'] in dir(api_models):
14+
cls = getattr(api_models, obj['__type__'])
15+
return cls.parse_obj(obj)
1716
return obj
1817

1918

20-
# Encoder function
19+
# Encoder function
2120
def pydantic_dumps(obj):
2221
return dumps(obj, cls=PydanticSerializer)
2322

0 commit comments

Comments
 (0)