From ef54cae1b77a189151713001640d81e697d180cb Mon Sep 17 00:00:00 2001 From: Kory Draughn Date: Mon, 24 Aug 2026 12:22:38 -0400 Subject: [PATCH] [#512] Sync names for physical quotas with logical quotas --- API.md | 12 +++++------ endpoints/physical_quotas/src/main.cpp | 28 ++++++++++++------------ test/test_irods_http_api.py | 30 +++++++++++++------------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/API.md b/API.md index 5f19e601..b3d7523d 100644 --- a/API.md +++ b/API.md @@ -1514,8 +1514,8 @@ If an HTTP status code of 200 is returned, the body of the response will contain "global_quotas": [ { "group": "string", - "limit": 0, - "over": 0, + "maximum_bytes": 0, + "over_bytes": 0, "modified_at": "string" }, @@ -1525,8 +1525,8 @@ If an HTTP status code of 200 is returned, the body of the response will contain { "group": "string", "resource": "string", - "limit": 0, - "over": 0, + "maximum_bytes": 0, + "over_bytes": 0, "modified_at": "string" }, @@ -1554,12 +1554,12 @@ curl http://localhost:/irods-http-api//physical-quotas \ --data-urlencode 'op=set_group_quota' \ --data-urlencode 'group=' \ # The group to which the new quota applies. --data-urlencode 'resource=' \ # The resource to which the new quota applies. Optional. - --data-urlencode 'quota=' # The number of bytes which will serve as the quota limit. + --data-urlencode 'maximum-bytes=' # The total number of bytes that can be stored by a group. ``` If a target resource is not provided via the `resource` parameter, the quota will be treated as a global quota. Writing data to one or more resources will count towards the group quota. -To remove a quota, set the quota limit to 0 (i.e. `quota=0`). +To remove a quota, set `maximum-bytes` to 0. #### Response diff --git a/endpoints/physical_quotas/src/main.cpp b/endpoints/physical_quotas/src/main.cpp index 6a33e161..3193ee87 100644 --- a/endpoints/physical_quotas/src/main.cpp +++ b/endpoints/physical_quotas/src/main.cpp @@ -119,8 +119,8 @@ namespace resource_quotas.emplace_back(json{ {"group", std::move(row[0])}, {"resource", std::move(row[2])}, - {"limit", std::stoll(row[3])}, - {"over", std::stoll(row[4])}, + {"maximum_bytes", std::stoll(row[3])}, + {"over_bytes", std::stoll(row[4])}, {"modified_at", std::move(row[5])}}); } @@ -132,8 +132,8 @@ namespace for (auto&& row : irods::query{static_cast(conn), global_quotas_query}) { global_quotas.emplace_back(json{ {"group", std::move(row[0])}, - {"limit", std::stoll(row[2])}, - {"over", std::stoll(row[3])}, + {"maximum_bytes", std::stoll(row[2])}, + {"over_bytes", std::stoll(row[3])}, {"modified_at", std::move(row[4])}}); } } @@ -145,8 +145,8 @@ namespace resource_quotas.emplace_back(json{ {"group", std::move(row[0])}, {"resource", std::move(row[2])}, - {"limit", std::stoll(row[3])}, - {"over", std::stoll(row[4])}, + {"maximum_bytes", std::stoll(row[3])}, + {"over_bytes", std::stoll(row[4])}, {"modified_at", std::move(row[5])}}); } @@ -156,8 +156,8 @@ namespace for (auto&& row : irods::query{static_cast(conn), global_quotas_query}) { global_quotas.emplace_back(json{ {"group", std::move(row[0])}, - {"limit", std::stoll(row[2])}, - {"over", std::stoll(row[3])}, + {"maximum_bytes", std::stoll(row[2])}, + {"over_bytes", std::stoll(row[3])}, {"modified_at", std::move(row[4])}}); } } @@ -218,20 +218,20 @@ namespace return _sess_ptr->send(irods::http::fail(res, http::status::bad_request)); } - const auto quota_iter = _args.find("quota"); + const auto max_bytes_iter = _args.find("maximum-bytes"); if (group_iter == std::end(_args)) { - logging::error(*_sess_ptr, "{}: Missing [quota] parameter.", fn); + logging::error(*_sess_ptr, "{}: Missing [maximum-bytes] parameter.", fn); return _sess_ptr->send(irods::http::fail(res, http::status::bad_request)); } try { - if (std::stoll(quota_iter->second) < 0) { - logging::error(*_sess_ptr, "{}: Value for [quota] parameter is less than 0.", fn); + if (std::stoll(max_bytes_iter->second) < 0) { + logging::error(*_sess_ptr, "{}: Value for [maximum-bytes] parameter is less than 0.", fn); return _sess_ptr->send(irods::http::fail(res, http::status::bad_request)); } } catch (const std::exception& e) { - logging::error(*_sess_ptr, "{}: Invalid value for [quota] parameter: {}", fn, e.what()); + logging::error(*_sess_ptr, "{}: Invalid value for [maximum-bytes] parameter: {}", fn, e.what()); return _sess_ptr->send(irods::http::fail(res, http::status::bad_request)); } @@ -239,7 +239,7 @@ namespace input.arg0 = "set-quota"; input.arg1 = "group"; input.arg2 = group_iter->second.c_str(); - input.arg4 = quota_iter->second.c_str(); + input.arg4 = max_bytes_iter->second.c_str(); // Apply the quota as a resource quota if the user set the resource parameter. // Otherwise, apply it as a global quota across all resources. diff --git a/test/test_irods_http_api.py b/test/test_irods_http_api.py index 02c3ed79..013ff74c 100644 --- a/test/test_irods_http_api.py +++ b/test/test_irods_http_api.py @@ -4819,7 +4819,7 @@ def test_setting_a_group_quota_for_a_specific_resource(self): 'op': 'set_group_quota', 'group': 'public', 'resource': resource, - 'quota': 10 + 'maximum-bytes': 10 }) self.logger.debug(r.content) self.assertEqual(r.status_code, 200) @@ -4845,8 +4845,8 @@ def test_setting_a_group_quota_for_a_specific_resource(self): self.assertEqual(r.status_code, 200) result = r.json() self.assertEqual(result['irods_response']['status_code'], 0) - self.assertEqual(result['resource_quotas'][0]['limit'], 10) - self.assertEqual(result['resource_quotas'][0]['over'], -10) + self.assertEqual(result['resource_quotas'][0]['maximum_bytes'], 10) + self.assertEqual(result['resource_quotas'][0]['over_bytes'], -10) # Create a data object which does not violate the quota limit. r = requests.post(f'{self.url_base}/data-objects', headers=rodsuser_headers, data={ @@ -4876,8 +4876,8 @@ def test_setting_a_group_quota_for_a_specific_resource(self): self.assertEqual(r.status_code, 200) result = r.json() self.assertEqual(result['irods_response']['status_code'], 0) - self.assertEqual(result['resource_quotas'][0]['limit'], 10) - self.assertEqual(result['resource_quotas'][0]['over'], -8) + self.assertEqual(result['resource_quotas'][0]['maximum_bytes'], 10) + self.assertEqual(result['resource_quotas'][0]['over_bytes'], -8) # Overwrite the data object. This puts the quota in violation. Any attempts to # write to the data object will result in an error. @@ -4939,7 +4939,7 @@ def test_setting_a_group_quota_for_a_specific_resource(self): 'op': 'set_group_quota', 'group': 'public', 'resource': resource, - 'quota': 0 + 'maximum-bytes': 0 }) self.logger.debug(r.content) @@ -4954,7 +4954,7 @@ def test_setting_a_group_quota_for_all_resources(self): r = requests.post(self.url_endpoint, headers=rodsadmin_headers, data={ 'op': 'set_group_quota', 'group': 'public', - 'quota': 10 + 'maximum-bytes': 10 }) self.logger.debug(r.content) self.assertEqual(r.status_code, 200) @@ -4979,8 +4979,8 @@ def test_setting_a_group_quota_for_all_resources(self): self.assertEqual(r.status_code, 200) result = r.json() self.assertEqual(result['irods_response']['status_code'], 0) - self.assertEqual(result['global_quotas'][0]['limit'], 10) - self.assertEqual(result['global_quotas'][0]['over'], -10) + self.assertEqual(result['global_quotas'][0]['maximum_bytes'], 10) + self.assertEqual(result['global_quotas'][0]['over_bytes'], -10) # Create a data object which does not violate the quota limit. r = requests.post(f'{self.url_base}/data-objects', headers=rodsuser_headers, data={ @@ -5008,8 +5008,8 @@ def test_setting_a_group_quota_for_all_resources(self): self.assertEqual(r.status_code, 200) result = r.json() self.assertEqual(result['irods_response']['status_code'], 0) - self.assertEqual(result['global_quotas'][0]['limit'], 10) - self.assertEqual(result['global_quotas'][0]['over'], -8) + self.assertEqual(result['global_quotas'][0]['maximum_bytes'], 10) + self.assertEqual(result['global_quotas'][0]['over_bytes'], -8) # Overwrite the data object. This puts the quota in violation. Any attempts to # write to the data object will result in an error. @@ -5067,7 +5067,7 @@ def test_setting_a_group_quota_for_all_resources(self): r = requests.post(self.url_endpoint, headers=rodsadmin_headers, data={ 'op': 'set_group_quota', 'group': 'public', - 'quota': 0 + 'maximum-bytes': 0 }) self.logger.debug(r.content) @@ -5080,7 +5080,7 @@ def test_server_returns_an_error_on_nonexistent_group(self): r = requests.post(self.url_endpoint, headers=rodsadmin_headers, data={ 'op': 'set_group_quota', 'group': 'does_not_exist', - 'quota': 10 + 'maximum-bytes': 10 }) self.logger.debug(r.content) self.assertEqual(r.status_code, 200) @@ -5096,7 +5096,7 @@ def test_server_returns_an_error_on_nonexistent_resource(self): 'op': 'set_group_quota', 'group': 'public', 'resource': 'does_not_exist', - 'quota': 10 + 'maximum-bytes': 10 }) self.logger.debug(r.content) self.assertEqual(r.status_code, 200) @@ -5119,7 +5119,7 @@ def test_server_returns_an_error_when_quota_value_is_invalid(self): r = requests.post(self.url_endpoint, headers=rodsadmin_headers, data={ 'op': 'set_group_quota', 'group': 'public', - 'quota': v + 'maximum-bytes': v }) self.logger.debug(r.content) self.assertEqual(r.status_code, 400)