diff --git a/linode_api4/groups/object_storage.py b/linode_api4/groups/object_storage.py index f13237c58..eb6a296b7 100644 --- a/linode_api4/groups/object_storage.py +++ b/linode_api4/groups/object_storage.py @@ -8,6 +8,7 @@ from linode_api4 import ( ObjectStorageEndpoint, ObjectStorageEndpointType, + ObjectStorageType, PaginatedList, ) from linode_api4.errors import UnexpectedResponseError @@ -70,6 +71,24 @@ def keys(self, *filters): """ return self.client._get_and_filter(ObjectStorageKeys, *filters) + def types(self, *filters): + """ + Returns a paginated list of Object Storage Types. + + API Documentation: https://techdocs.akamai.com/linode-api/reference/get-object-storage-types + + :param filters: Any number of filters to apply to this query. + See :doc:`Filtering Collections` + for more details on filtering. + + :returns: A Paginated List of Object Storage types that match the query. + :rtype: PaginatedList of ObjectStorageType + """ + + return self.client._get_and_filter( + ObjectStorageType, *filters, endpoint="/object-storage/types" + ) + def keys_create( self, label: str, diff --git a/linode_api4/objects/object_storage.py b/linode_api4/objects/object_storage.py index 76a3945e2..be1fd0cc7 100644 --- a/linode_api4/objects/object_storage.py +++ b/linode_api4/objects/object_storage.py @@ -4,6 +4,7 @@ from deprecated import deprecated +from linode_api4.common import Price, RegionPrice from linode_api4.errors import UnexpectedResponseError from linode_api4.objects import ( Base, @@ -50,6 +51,24 @@ class ObjectStorageEndpoint(JSONObject): s3_endpoint: Optional[str] = None +class ObjectStorageType(Base): + """ + An ObjectStorageType represents the structure of a valid Object Storage type. + Currently, the ObjectStorageType can only be retrieved by listing, i.e.: + types = client.object_storage.types() + + API documentation: https://techdocs.akamai.com/linode-api/reference/get-object-storage-types + """ + + properties = { + "id": Property(identifier=True), + "label": Property(), + "price": Property(json_object=Price), + "region_prices": Property(json_object=RegionPrice), + "transfer": Property(), + } + + class ObjectStorageBucket(DerivedBase): """ A bucket where objects are stored in. diff --git a/test/fixtures/object-storage_types.json b/test/fixtures/object-storage_types.json new file mode 100644 index 000000000..029823580 --- /dev/null +++ b/test/fixtures/object-storage_types.json @@ -0,0 +1,23 @@ +{ + "data": [ + { + "id": "objectstorage", + "label": "Object Storage", + "price": { + "hourly": 0.0015, + "monthly": 0.1 + }, + "region_prices": [ + { + "hourly": 0.00018, + "id": "us-east", + "monthly": 0.12 + } + ], + "transfer": 0 + } + ], + "page": 1, + "pages": 1, + "results": 1 +} \ No newline at end of file diff --git a/test/integration/models/object_storage/test_obj.py b/test/integration/models/object_storage/test_obj.py index 0f3e39f33..33ce8dfbe 100644 --- a/test/integration/models/object_storage/test_obj.py +++ b/test/integration/models/object_storage/test_obj.py @@ -3,6 +3,7 @@ import pytest +from linode_api4.common import RegionPrice from linode_api4.linode_client import LinodeClient from linode_api4.objects.object_storage import ( ObjectStorageACL, @@ -11,6 +12,7 @@ ObjectStorageEndpointType, ObjectStorageKeyPermission, ObjectStorageKeys, + ObjectStorageType, ) @@ -191,3 +193,22 @@ def test_get_buckets_in_cluster( ): cluster = test_linode_client.load(ObjectStorageCluster, bucket.cluster) assert any(bucket.id == b.id for b in cluster.buckets_in_cluster()) + + +def test_object_storage_types(test_linode_client): + types = test_linode_client.object_storage.types() + + if len(types) > 0: + for object_storage_type in types: + assert type(object_storage_type) is ObjectStorageType + assert object_storage_type.price.monthly is None or ( + isinstance(object_storage_type.price.monthly, (float, int)) + and object_storage_type.price.monthly >= 0 + ) + if len(object_storage_type.region_prices) > 0: + region_price = object_storage_type.region_prices[0] + assert type(region_price) is RegionPrice + assert object_storage_type.price.monthly is None or ( + isinstance(object_storage_type.price.monthly, (float, int)) + and object_storage_type.price.monthly >= 0 + ) diff --git a/test/unit/linode_client_test.py b/test/unit/linode_client_test.py index 41cb9100d..c79c0a88d 100644 --- a/test/unit/linode_client_test.py +++ b/test/unit/linode_client_test.py @@ -980,6 +980,21 @@ def test_get_keys(self): self.assertEqual(key2.access_key, "testAccessKeyHere456") self.assertEqual(key2.secret_key, "[REDACTED]") + def test_object_storage_types(self): + """ + Tests that a list of ObjectStorageTypes can be retrieved + """ + types = self.client.object_storage.types() + self.assertEqual(len(types), 1) + self.assertEqual(types[0].id, "objectstorage") + self.assertEqual(types[0].label, "Object Storage") + self.assertEqual(types[0].price.hourly, 0.0015) + self.assertEqual(types[0].price.monthly, 0.1) + self.assertEqual(types[0].region_prices[0].id, "us-east") + self.assertEqual(types[0].region_prices[0].hourly, 0.00018) + self.assertEqual(types[0].region_prices[0].monthly, 0.12) + self.assertEqual(types[0].transfer, 0) + def test_keys_create(self): """ Tests that you can create Object Storage Keys