Skip to content

Commit 751180e

Browse files
Project: Limits Visibility M1 (#544)
* Support Object Storage Quota Limits Visibility (#531) * obj quota * add comment * build json object * add obj quotas int tests (#535) * Update Object Storage quota doc link (#543) --------- Co-authored-by: Youjung Kim <126618609+ykim-akamai@users.noreply.github.com>
1 parent 8cc03ee commit 751180e

File tree

7 files changed

+212
-0
lines changed

7 files changed

+212
-0
lines changed

linode_api4/groups/object_storage.py

+16
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
ObjectStorageCluster,
2222
ObjectStorageKeyPermission,
2323
ObjectStorageKeys,
24+
ObjectStorageQuota,
2425
)
2526
from linode_api4.util import drop_null_keys
2627

@@ -517,3 +518,18 @@ def object_url_create(
517518
)
518519

519520
return MappedObject(**result)
521+
522+
def quotas(self, *filters):
523+
"""
524+
Lists the active ObjectStorage-related quotas applied to your account.
525+
526+
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-object-storage-quotas
527+
528+
:param filters: Any number of filters to apply to this query.
529+
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
530+
for more details on filtering.
531+
532+
:returns: A list of Object Storage Quotas that matched the query.
533+
:rtype: PaginatedList of ObjectStorageQuota
534+
"""
535+
return self.client._get_and_filter(ObjectStorageQuota, *filters)

linode_api4/objects/object_storage.py

+49
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ class ObjectStorageEndpoint(JSONObject):
5151
s3_endpoint: Optional[str] = None
5252

5353

54+
@dataclass
55+
class ObjectStorageQuotaUsage(JSONObject):
56+
"""
57+
ObjectStorageQuotaUsage contains the fields of an object storage quota usage information.
58+
"""
59+
60+
quota_limit: int = 0
61+
usage: int = 0
62+
63+
5464
class ObjectStorageType(Base):
5565
"""
5666
An ObjectStorageType represents the structure of a valid Object Storage type.
@@ -566,3 +576,42 @@ class ObjectStorageKeys(Base):
566576
"limited": Property(),
567577
"regions": Property(unordered=True),
568578
}
579+
580+
581+
class ObjectStorageQuota(Base):
582+
"""
583+
An Object Storage related quota information on your account.
584+
Object Storage Quota related features are under v4beta and may not currently be available to all users.
585+
586+
API documentation: https://techdocs.akamai.com/linode-api/reference/get-object-storage-quota
587+
"""
588+
589+
api_endpoint = "/object-storage/quotas/{quota_id}"
590+
id_attribute = "quota_id"
591+
592+
properties = {
593+
"quota_id": Property(identifier=True),
594+
"quota_name": Property(),
595+
"endpoint_type": Property(),
596+
"s3_endpoint": Property(),
597+
"description": Property(),
598+
"quota_limit": Property(),
599+
"resource_metric": Property(),
600+
}
601+
602+
def usage(self):
603+
"""
604+
Gets usage data for a specific ObjectStorage Quota resource you can have on your account and the current usage for that resource.
605+
606+
API documentation: https://techdocs.akamai.com/linode-api/reference/get-object-storage-quota-usage
607+
608+
:returns: The Object Storage Quota usage.
609+
:rtype: ObjectStorageQuotaUsage
610+
"""
611+
612+
result = self._client.get(
613+
f"{type(self).api_endpoint}/usage",
614+
model=self,
615+
)
616+
617+
return ObjectStorageQuotaUsage.from_json(result)
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"data": [
3+
{
4+
"quota_id": "obj-objects-us-ord-1",
5+
"quota_name": "Object Storage Maximum Objects",
6+
"description": "Maximum number of Objects this customer is allowed to have on this endpoint.",
7+
"endpoint_type": "E1",
8+
"s3_endpoint": "us-iad-1.linodeobjects.com",
9+
"quota_limit": 50,
10+
"resource_metric": "object"
11+
},
12+
{
13+
"quota_id": "obj-bucket-us-ord-1",
14+
"quota_name": "Object Storage Maximum Buckets",
15+
"description": "Maximum number of buckets this customer is allowed to have on this endpoint.",
16+
"endpoint_type": "E1",
17+
"s3_endpoint": "us-iad-1.linodeobjects.com",
18+
"quota_limit": 50,
19+
"resource_metric": "bucket"
20+
}
21+
],
22+
"page": 1,
23+
"pages": 1,
24+
"results": 2
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"quota_id": "obj-objects-us-ord-1",
3+
"quota_name": "Object Storage Maximum Objects",
4+
"description": "Maximum number of Objects this customer is allowed to have on this endpoint.",
5+
"endpoint_type": "E1",
6+
"s3_endpoint": "us-iad-1.linodeobjects.com",
7+
"quota_limit": 50,
8+
"resource_metric": "object"
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"quota_limit": 100,
3+
"usage": 10
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from linode_api4.objects.object_storage import (
2+
ObjectStorageQuota,
3+
ObjectStorageQuotaUsage,
4+
)
5+
6+
7+
def test_list_obj_storage_quotas(test_linode_client):
8+
quotas = test_linode_client.object_storage.quotas()
9+
10+
target_quota_id = "obj-buckets-us-sea-1.linodeobjects.com"
11+
12+
found_quota = None
13+
for quota in quotas:
14+
if quota.quota_id == target_quota_id:
15+
found_quota = quota
16+
break
17+
18+
assert (
19+
found_quota is not None
20+
), f"Quota with ID {target_quota_id} not found."
21+
22+
assert found_quota.quota_id == "obj-buckets-us-sea-1.linodeobjects.com"
23+
assert found_quota.quota_name == "max_buckets"
24+
assert found_quota.endpoint_type == "E1"
25+
assert found_quota.s3_endpoint == "us-sea-1.linodeobjects.com"
26+
assert (
27+
found_quota.description
28+
== "Maximum number of buckets this customer is allowed to have on this endpoint"
29+
)
30+
assert found_quota.quota_limit == 1000
31+
assert found_quota.resource_metric == "bucket"
32+
33+
34+
def test_get_obj_storage_quota(test_linode_client):
35+
quota_id = "obj-objects-us-ord-1.linodeobjects.com"
36+
quota = test_linode_client.load(ObjectStorageQuota, quota_id)
37+
38+
assert quota.quota_id == "obj-objects-us-ord-1.linodeobjects.com"
39+
assert quota.quota_name == "max_objects"
40+
assert quota.endpoint_type == "E1"
41+
assert quota.s3_endpoint == "us-ord-1.linodeobjects.com"
42+
assert (
43+
quota.description
44+
== "Maximum number of objects this customer is allowed to have on this endpoint"
45+
)
46+
assert quota.quota_limit == 100000000
47+
assert quota.resource_metric == "object"
48+
49+
50+
def test_get_obj_storage_quota_usage(test_linode_client):
51+
quota_id = "obj-objects-us-ord-1.linodeobjects.com"
52+
quota = test_linode_client.load(ObjectStorageQuota, quota_id)
53+
54+
quota_usage = quota.usage()
55+
56+
assert isinstance(quota_usage, ObjectStorageQuotaUsage)
57+
assert quota_usage.quota_limit == 100000000
58+
assert quota_usage.usage >= 0

test/unit/objects/object_storage_test.py

+51
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
ObjectStorageACL,
77
ObjectStorageBucket,
88
ObjectStorageCluster,
9+
ObjectStorageQuota,
910
)
1011

1112

@@ -284,3 +285,53 @@ def test_object_acl_config_update(self):
284285
"name": "example",
285286
},
286287
)
288+
289+
def test_quota_get_and_list(self):
290+
"""
291+
Test that you can get and list an Object storage quota and usage information.
292+
"""
293+
quota = ObjectStorageQuota(
294+
self.client,
295+
"obj-objects-us-ord-1",
296+
)
297+
298+
self.assertIsNotNone(quota)
299+
self.assertEqual(quota.quota_id, "obj-objects-us-ord-1")
300+
self.assertEqual(quota.quota_name, "Object Storage Maximum Objects")
301+
self.assertEqual(
302+
quota.description,
303+
"Maximum number of Objects this customer is allowed to have on this endpoint.",
304+
)
305+
self.assertEqual(quota.endpoint_type, "E1")
306+
self.assertEqual(quota.s3_endpoint, "us-iad-1.linodeobjects.com")
307+
self.assertEqual(quota.quota_limit, 50)
308+
self.assertEqual(quota.resource_metric, "object")
309+
310+
quota_usage_url = "/object-storage/quotas/obj-objects-us-ord-1/usage"
311+
with self.mock_get(quota_usage_url) as m:
312+
usage = quota.usage()
313+
self.assertIsNotNone(usage)
314+
self.assertEqual(m.call_url, quota_usage_url)
315+
self.assertEqual(usage.quota_limit, 100)
316+
self.assertEqual(usage.usage, 10)
317+
318+
quota_list_url = "/object-storage/quotas"
319+
with self.mock_get(quota_list_url) as m:
320+
quotas = self.client.object_storage.quotas()
321+
self.assertIsNotNone(quotas)
322+
self.assertEqual(m.call_url, quota_list_url)
323+
self.assertEqual(len(quotas), 2)
324+
self.assertEqual(quotas[0].quota_id, "obj-objects-us-ord-1")
325+
self.assertEqual(
326+
quotas[0].quota_name, "Object Storage Maximum Objects"
327+
)
328+
self.assertEqual(
329+
quotas[0].description,
330+
"Maximum number of Objects this customer is allowed to have on this endpoint.",
331+
)
332+
self.assertEqual(quotas[0].endpoint_type, "E1")
333+
self.assertEqual(
334+
quotas[0].s3_endpoint, "us-iad-1.linodeobjects.com"
335+
)
336+
self.assertEqual(quotas[0].quota_limit, 50)
337+
self.assertEqual(quotas[0].resource_metric, "object")

0 commit comments

Comments
 (0)