Skip to content

Commit

Permalink
Merge pull request #158 from nerc-project/rgw-disable-zero-quota
Browse files Browse the repository at this point in the history
openstack: require swift/object/radosgw quotas to be >= 0
  • Loading branch information
jtriley authored May 14, 2024
2 parents 0794055 + af75e98 commit 92938e1
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ def handle(self, *args, **options):

failed_validation = Command.sync_users(project_id, allocation, allocator, options["apply"])

obj_key = openstack.QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB]

for attr in attributes.ALLOCATION_QUOTA_ATTRIBUTES:
if 'OpenStack' in attr.name:
key = openstack.QUOTA_KEY_MAPPING_ALL_KEYS.get(attr.name, None)
Expand All @@ -116,7 +118,15 @@ def handle(self, *args, **options):

expected_value = allocation.get_attribute(attr.name)
current_value = quota.get(key, None)
if expected_value is None and current_value:
if key == obj_key and expected_value <= 0:
expected_obj_value = 1
current_value = allocator.object(project_id).head_account().get(obj_key)
if current_value != expected_obj_value:
failed_validation = True
msg = (f'Value for quota for {attr.name} = {current_value} does not match expected'
f' value of {expected_obj_value} on allocation {allocation_str}')
logger.warning(msg)
elif expected_value is None and current_value:
msg = (f'Attribute "{attr.name}" expected on allocation {allocation_str} but not set.'
f' Current quota is {current_value}.')
if options['apply']:
Expand All @@ -132,9 +142,13 @@ def handle(self, *args, **options):
logger.warning(msg)

if failed_validation and options['apply']:
allocator.set_quota(
allocation.get_attribute(attributes.ALLOCATION_PROJECT_ID)
)
try:
allocator.set_quota(
allocation.get_attribute(attributes.ALLOCATION_PROJECT_ID)
)
except Exception as e:
logger.error(f'setting openstack quota failed: {e}')
continue
logger.warning(f'Quota for allocation {allocation_str} was out of date. Reapplied!')

# Deal with OpenShift
Expand Down Expand Up @@ -229,8 +243,10 @@ def handle(self, *args, **options):
current_value = round(current_value / suffix["Mi"])
elif "Storage" in attr.name:
current_value = round(current_value / suffix["Gi"])
elif current_value and current_value == "0":
current_value = 0

if expected_value is None and current_value:
if expected_value is None and current_value is not None:
msg = (
f'Attribute "{attr.name}" expected on allocation {allocation_str} but not set.'
f" Current quota is {current_value}."
Expand All @@ -249,7 +265,11 @@ def handle(self, *args, **options):
logger.warning(msg)

if options["apply"]:
allocator.set_quota(project_id)
logger.warning(
f"Quota for allocation {project_id} was out of date. Reapplied!"
)
try:
allocator.set_quota(project_id)
logger.warning(
f"Quota for allocation {project_id} was out of date. Reapplied!"
)
except Exception as e:
logger.error(f'setting openshift quota failed: {e}')
continue
9 changes: 6 additions & 3 deletions src/coldfront_plugin_cloud/openstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,12 @@ def _set_object_quota(self, project_id, payload):
# Note(knikolla): For consistency with other OpenStack
# quotas we're storing this as GB on the attribute and
# converting to bytes for Swift.
payload[QUOTA_KEY_MAPPING['object']['keys'][
attributes.QUOTA_OBJECT_GB]
] *= GB_IN_BYTES
obj_q_mapping = QUOTA_KEY_MAPPING['object']['keys'][
attributes.QUOTA_OBJECT_GB
]
payload[obj_q_mapping] *= GB_IN_BYTES
if payload[obj_q_mapping] <= 0:
payload[obj_q_mapping] = 1
self.object(project_id).post_account(headers=payload)
except ksa_exceptions.catalog.EndpointNotFound:
logger.debug('No swift available, skipping its quota.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,40 @@ def test_new_allocation_with_quantity(self):
actual_nova_quota = self.compute.quotas.get(openstack_project.id)
self.assertEqual(actual_nova_quota.__getattr__('cores'), 200)

# Change allocation attributes for object store quota
current_quota = allocator.get_quota(openstack_project.id)
obj_key = openstack.QUOTA_KEY_MAPPING['object']['keys'][attributes.QUOTA_OBJECT_GB]
if obj_key in current_quota.keys():
utils.set_attribute_on_allocation(allocation, attributes.QUOTA_OBJECT_GB, 6)
self.assertEqual(allocation.get_attribute(attributes.QUOTA_OBJECT_GB), 6)
tasks.activate_allocation(allocation.pk)
self.assertEqual(
allocation.get_attribute(attributes.QUOTA_OBJECT_GB),
allocator.get_quota(openstack_project.id)[obj_key]
)

# setting 0 object quota in coldfront -> 1 byte quota in swift/rgw
utils.set_attribute_on_allocation(allocation, attributes.QUOTA_OBJECT_GB, 0)
self.assertEqual(allocation.get_attribute(attributes.QUOTA_OBJECT_GB), 0)
tasks.activate_allocation(allocation.pk)
obj_quota = allocator.object(project_id).head_account().get(obj_key)
self.assertEqual(int(obj_quota), 1)

# test validate_allocations works for object quota set to 0
utils.set_attribute_on_allocation(allocation, attributes.QUOTA_OBJECT_GB, 3)
self.assertEqual(allocation.get_attribute(attributes.QUOTA_OBJECT_GB), 3)
tasks.activate_allocation(allocation.pk)
self.assertEqual(
allocation.get_attribute(attributes.QUOTA_OBJECT_GB),
allocator.get_quota(openstack_project.id)[obj_key]
)
utils.set_attribute_on_allocation(allocation, attributes.QUOTA_OBJECT_GB, 0)
self.assertEqual(allocation.get_attribute(attributes.QUOTA_OBJECT_GB), 0)
call_command('validate_allocations', apply=True)
obj_quota = allocator.object(project_id).head_account().get(obj_key)
self.assertEqual(int(obj_quota), 1)


def test_reactivate_allocation(self):
user = self.new_user()
project = self.new_project(pi=user)
Expand Down

0 comments on commit 92938e1

Please sign in to comment.