1+ import re
2+ import warnings
13from typing import List , Optional , Union
24from urllib import parse
35
6+ from deprecated import deprecated
7+
48from linode_api4 .errors import UnexpectedResponseError
59from linode_api4 .groups import Group
610from linode_api4 .objects import (
913 ObjectStorageACL ,
1014 ObjectStorageBucket ,
1115 ObjectStorageCluster ,
16+ ObjectStorageKeyPermission ,
1217 ObjectStorageKeys ,
1318)
1419from linode_api4 .util import drop_null_keys
@@ -20,8 +25,14 @@ class ObjectStorageGroup(Group):
2025 available clusters, buckets, and managing keys and TLS/SSL certs, etc.
2126 """
2227
28+ @deprecated (
29+ reason = "deprecated to use regions list API for listing available OJB clusters"
30+ )
2331 def clusters (self , * filters ):
2432 """
33+ This endpoint will be deprecated to use the regions list API to list available OBJ clusters,
34+ and a new access key API will directly expose the S3 endpoint hostname.
35+
2536 Returns a list of available Object Storage Clusters. You may filter
2637 this query to return only Clusters that are available in a specific region::
2738
@@ -58,6 +69,7 @@ def keys_create(
5869 self ,
5970 label : str ,
6071 bucket_access : Optional [Union [dict , List [dict ]]] = None ,
72+ regions : Optional [List [str ]] = None ,
6173 ):
6274 """
6375 Creates a new Object Storage keypair that may be used to interact directly
@@ -97,14 +109,16 @@ def keys_create(
97109
98110 :param label: The label for this keypair, for identification only.
99111 :type label: str
100- :param bucket_access: One or a list of dicts with keys "cluster,"
101- "permissions", and "bucket_name". If given, the
102- resulting Object Storage keys will only have the
103- requested level of access to the requested buckets,
104- if they exist and are owned by you. See the provided
105- :any:`bucket_access` function for a convenient way
106- to create these dicts.
107- :type bucket_access: dict or list of dict
112+ :param bucket_access: One or a list of dicts with keys "cluster," "region",
113+ "permissions", and "bucket_name". "cluster" key is
114+ deprecated because multiple cluster can be placed
115+ in the same region. Please consider switching to
116+ regions. If given, the resulting Object Storage keys
117+ will only have the requested level of access to the
118+ requested buckets, if they exist and are owned by
119+ you. See the provided :any:`bucket_access` function
120+ for a convenient way to create these dicts.
121+ :type bucket_access: Optional[Union[dict, List[dict]]]
108122
109123 :returns: The new keypair, with the secret key populated.
110124 :rtype: ObjectStorageKeys
@@ -115,22 +129,35 @@ def keys_create(
115129 if not isinstance (bucket_access , list ):
116130 bucket_access = [bucket_access ]
117131
118- ba = [
119- {
120- "permissions" : c .get ("permissions" ),
121- "bucket_name" : c .get ("bucket_name" ),
122- "cluster" : (
123- c .id
124- if "cluster" in c
125- and issubclass (type (c ["cluster" ]), Base )
126- else c .get ("cluster" )
127- ),
132+ ba = []
133+ for access_rule in bucket_access :
134+ access_rule_json = {
135+ "permissions" : access_rule .get ("permissions" ),
136+ "bucket_name" : access_rule .get ("bucket_name" ),
128137 }
129- for c in bucket_access
130- ]
138+
139+ if "region" in access_rule :
140+ access_rule_json ["region" ] = access_rule .get ("region" )
141+ elif "cluster" in access_rule :
142+ warnings .warn (
143+ "'cluster' is a deprecated attribute, "
144+ "please consider using 'region' instead." ,
145+ DeprecationWarning ,
146+ )
147+ access_rule_json ["cluster" ] = (
148+ access_rule .id
149+ if "cluster" in access_rule
150+ and issubclass (type (access_rule ["cluster" ]), Base )
151+ else access_rule .get ("cluster" )
152+ )
153+
154+ ba .append (access_rule_json )
131155
132156 params ["bucket_access" ] = ba
133157
158+ if regions is not None :
159+ params ["regions" ] = regions
160+
134161 result = self .client .post ("/object-storage/keys" , data = params )
135162
136163 if not "id" in result :
@@ -142,9 +169,74 @@ def keys_create(
142169 ret = ObjectStorageKeys (self .client , result ["id" ], result )
143170 return ret
144171
145- def bucket_access (self , cluster , bucket_name , permissions ):
146- return ObjectStorageBucket .access (
147- self , cluster , bucket_name , permissions
172+ @classmethod
173+ def bucket_access (
174+ cls ,
175+ cluster_or_region : str ,
176+ bucket_name : str ,
177+ permissions : Union [str , ObjectStorageKeyPermission ],
178+ ):
179+ """
180+ Returns a dict formatted to be included in the `bucket_access` argument
181+ of :any:`keys_create`. See the docs for that method for an example of
182+ usage.
183+
184+ :param cluster_or_region: The region or Object Storage cluster to grant access in.
185+ :type cluster_or_region: str
186+ :param bucket_name: The name of the bucket to grant access to.
187+ :type bucket_name: str
188+ :param permissions: The permissions to grant. Should be one of "read_only"
189+ or "read_write".
190+ :type permissions: Union[str, ObjectStorageKeyPermission]
191+ :param use_region: Whether to use region mode.
192+ :type use_region: bool
193+
194+ :returns: A dict formatted correctly for specifying bucket access for
195+ new keys.
196+ :rtype: dict
197+ """
198+
199+ result = {
200+ "bucket_name" : bucket_name ,
201+ "permissions" : permissions ,
202+ }
203+
204+ if cls .is_cluster (cluster_or_region ):
205+ warnings .warn (
206+ "Cluster ID for Object Storage APIs has been deprecated. "
207+ "Please consider switch to a region ID (e.g., from `us-mia-1` to `us-mia`)" ,
208+ DeprecationWarning ,
209+ )
210+ result ["cluster" ] = cluster_or_region
211+ else :
212+ result ["region" ] = cluster_or_region
213+
214+ return result
215+
216+ def buckets_in_region (self , region : str , * filters ):
217+ """
218+ Returns a list of Buckets in the region belonging to this Account.
219+
220+ This endpoint is available for convenience.
221+ It is recommended that instead you use the more fully-featured S3 API directly.
222+
223+ API Documentation: https://www.linode.com/docs/api/object-storage/#object-storage-buckets-in-cluster-list
224+
225+ :param filters: Any number of filters to apply to this query.
226+ See :doc:`Filtering Collections</linode_api4/objects/filtering>`
227+ for more details on filtering.
228+
229+ :param region: The ID of an object storage region (e.g. `us-mia-1`).
230+ :type region: str
231+
232+ :returns: A list of Object Storage Buckets that in the requested cluster.
233+ :rtype: PaginatedList of ObjectStorageBucket
234+ """
235+
236+ return self .client ._get_and_filter (
237+ ObjectStorageBucket ,
238+ * filters ,
239+ endpoint = f"/object-storage/buckets/{ region } " ,
148240 )
149241
150242 def cancel (self ):
@@ -197,10 +289,14 @@ def buckets(self, *filters):
197289 """
198290 return self .client ._get_and_filter (ObjectStorageBucket , * filters )
199291
292+ @staticmethod
293+ def is_cluster (cluster_or_region : str ):
294+ return bool (re .match (r"^[a-z]{2}-[a-z]+-[0-9]+$" , cluster_or_region ))
295+
200296 def bucket_create (
201297 self ,
202- cluster ,
203- label ,
298+ cluster_or_region : Union [ str , ObjectStorageCluster ] ,
299+ label : str ,
204300 acl : ObjectStorageACL = ObjectStorageACL .PRIVATE ,
205301 cors_enabled = False ,
206302 ):
@@ -240,17 +336,30 @@ def bucket_create(
240336 :returns: A Object Storage Buckets that created by user.
241337 :rtype: ObjectStorageBucket
242338 """
243- cluster_id = (
244- cluster .id if isinstance (cluster , ObjectStorageCluster ) else cluster
339+ cluster_or_region_id = (
340+ cluster_or_region .id
341+ if isinstance (cluster_or_region , ObjectStorageCluster )
342+ else cluster_or_region
245343 )
246344
247345 params = {
248- "cluster" : cluster_id ,
249346 "label" : label ,
250347 "acl" : acl ,
251348 "cors_enabled" : cors_enabled ,
252349 }
253350
351+ if self .is_cluster (cluster_or_region_id ):
352+ warnings .warn (
353+ "The cluster parameter has been deprecated for creating a object "
354+ "storage bucket. Please consider switching to a region value. For "
355+ "example, a cluster value of `us-mia-1` can be translated to a "
356+ "region value of `us-mia`." ,
357+ DeprecationWarning ,
358+ )
359+ params ["cluster" ] = cluster_or_region_id
360+ else :
361+ params ["region" ] = cluster_or_region_id
362+
254363 result = self .client .post ("/object-storage/buckets" , data = params )
255364
256365 if not "label" in result or not "cluster" in result :
@@ -263,21 +372,21 @@ def bucket_create(
263372 self .client , result ["label" ], result ["cluster" ], result
264373 )
265374
266- def object_acl_config (self , cluster_id , bucket , name = None ):
375+ def object_acl_config (self , cluster_or_region_id : str , bucket , name = None ):
267376 return ObjectStorageBucket (
268- self .client , bucket , cluster_id
377+ self .client , bucket , cluster_or_region_id
269378 ).object_acl_config (name )
270379
271380 def object_acl_config_update (
272- self , cluster_id , bucket , acl : ObjectStorageACL , name
381+ self , cluster_or_region_id , bucket , acl : ObjectStorageACL , name
273382 ):
274383 return ObjectStorageBucket (
275- self .client , bucket , cluster_id
384+ self .client , bucket , cluster_or_region_id
276385 ).object_acl_config_update (acl , name )
277386
278387 def object_url_create (
279388 self ,
280- cluster_id ,
389+ cluster_or_region_id ,
281390 bucket ,
282391 method ,
283392 name ,
@@ -294,8 +403,8 @@ def object_url_create(
294403
295404 API Documentation: https://www.linode.com/docs/api/object-storage/#object-storage-object-url-create
296405
297- :param cluster_id : The ID of the cluster this bucket exists in.
298- :type cluster_id : str
406+ :param cluster_or_region_id : The ID of the cluster or region this bucket exists in.
407+ :type cluster_or_region_id : str
299408
300409 :param bucket: The bucket name.
301410 :type bucket: str
@@ -337,7 +446,7 @@ def object_url_create(
337446
338447 result = self .client .post (
339448 "/object-storage/buckets/{}/{}/object-url" .format (
340- parse .quote (str (cluster_id )), parse .quote (str (bucket ))
449+ parse .quote (str (cluster_or_region_id )), parse .quote (str (bucket ))
341450 ),
342451 data = drop_null_keys (params ),
343452 )
0 commit comments