Skip to content

Commit dcc92c9

Browse files
authored
Merge pull request #245 from QuanMPhm/244/parsing_quota
Fix parsing for Openshift quotas
2 parents 1cb7589 + 21c90e5 commit dcc92c9

File tree

2 files changed

+80
-45
lines changed

2 files changed

+80
-45
lines changed

src/coldfront_plugin_cloud/management/commands/validate_allocations.py

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,56 @@ def set_default_quota_on_allocation(allocation, allocator, coldfront_attr):
9292
utils.set_attribute_on_allocation(allocation, coldfront_attr, value)
9393
return value
9494

95+
@staticmethod
96+
def parse_quota_value(quota_str: str | None, attr: str) -> int | None:
97+
PATTERN = r"([0-9]+)(m|k|Ki|Mi|Gi|Ti|Pi|Ei|K|M|G|T|P|E)?"
98+
99+
suffix = {
100+
"Ki": 2**10,
101+
"Mi": 2**20,
102+
"Gi": 2**30,
103+
"Ti": 2**40,
104+
"Pi": 2**50,
105+
"Ei": 2**60,
106+
"m": 10**-3,
107+
"k": 10**3,
108+
"K": 10**3,
109+
"M": 10**6,
110+
"G": 10**9,
111+
"T": 10**12,
112+
"P": 10**15,
113+
"E": 10**18,
114+
}
115+
116+
if quota_str and quota_str != "0":
117+
result = re.search(PATTERN, quota_str)
118+
119+
if result is None:
120+
raise CommandError(
121+
f"Unable to parse quota_str = '{quota_str}' for {attr}"
122+
)
123+
124+
value = int(result.groups()[0])
125+
unit = result.groups()[1]
126+
127+
# Convert to number i.e. without any unit suffix
128+
129+
if unit is not None:
130+
quota_str = value * suffix[unit]
131+
else:
132+
quota_str = value
133+
134+
# Convert some attributes to units that coldfront uses
135+
136+
if "RAM" in attr:
137+
quota_str = round(quota_str / suffix["Mi"])
138+
elif "Storage" in attr:
139+
quota_str = round(quota_str / suffix["Gi"])
140+
elif quota_str and quota_str == "0":
141+
quota_str = 0
142+
143+
return quota_str
144+
95145
def check_institution_specific_code(self, allocation, apply):
96146
attr = attributes.ALLOCATION_INSTITUTION_SPECIFIC_CODE
97147
isc = allocation.get_attribute(attr)
@@ -256,51 +306,7 @@ def handle(self, *args, **options):
256306

257307
expected_value = allocation.get_attribute(attr)
258308
current_value = quota.get(key, None)
259-
260-
PATTERN = r"([0-9]+)(m|Ki|Mi|Gi|Ti|Pi|Ei|K|M|G|T|P|E)?"
261-
262-
suffix = {
263-
"Ki": 2**10,
264-
"Mi": 2**20,
265-
"Gi": 2**30,
266-
"Ti": 2**40,
267-
"Pi": 2**50,
268-
"Ei": 2**60,
269-
"m": 10**-3,
270-
"K": 10**3,
271-
"M": 10**6,
272-
"G": 10**9,
273-
"T": 10**12,
274-
"P": 10**15,
275-
"E": 10**18,
276-
}
277-
278-
if current_value and current_value != "0":
279-
result = re.search(PATTERN, current_value)
280-
281-
if result is None:
282-
raise CommandError(
283-
f"Unable to parse current_value = '{current_value}' for {attr}"
284-
)
285-
286-
value = int(result.groups()[0])
287-
unit = result.groups()[1]
288-
289-
# Convert to number i.e. without any unit suffix
290-
291-
if unit is not None:
292-
current_value = value * suffix[unit]
293-
else:
294-
current_value = value
295-
296-
# Convert some attributes to units that coldfront uses
297-
298-
if "RAM" in attr:
299-
current_value = round(current_value / suffix["Mi"])
300-
elif "Storage" in attr:
301-
current_value = round(current_value / suffix["Gi"])
302-
elif current_value and current_value == "0":
303-
current_value = 0
309+
current_value = self.parse_quota_value(current_value, attr)
304310

305311
if expected_value is None and current_value is not None:
306312
msg = (
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from django.core.management.base import CommandError
2+
3+
from coldfront_plugin_cloud.management.commands.validate_allocations import Command
4+
from coldfront_plugin_cloud.tests import base
5+
6+
7+
class TestParseQuotaUnit(base.TestBase):
8+
def test_parse_quota_unit(self):
9+
parse_quota_unit = Command().parse_quota_value
10+
answer_dict = [
11+
(("5m", "cpu"), 5 * 10**-3),
12+
(("10", "cpu"), 10),
13+
(("10k", "cpu"), 10 * 10**3),
14+
(("55M", "cpu"), 55 * 10**6),
15+
(("2G", "cpu"), 2 * 10**9),
16+
(("3T", "cpu"), 3 * 10**12),
17+
(("4P", "cpu"), 4 * 10**15),
18+
(("5E", "cpu"), 5 * 10**18),
19+
(("10", "memory"), 10),
20+
(("125Ki", "memory"), 125 * 2**10),
21+
(("55Mi", "memory"), 55 * 2**20),
22+
(("2Gi", "memory"), 2 * 2**30),
23+
(("3Ti", "memory"), 3 * 2**40),
24+
]
25+
for (input_value, resource_type), expected in answer_dict:
26+
self.assertEqual(parse_quota_unit(input_value, resource_type), expected)
27+
28+
with self.assertRaises(CommandError):
29+
parse_quota_unit("abc", "foo") # Non-numeric input

0 commit comments

Comments
 (0)