Skip to content

v5.28.0 #515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 5, 2025
2 changes: 1 addition & 1 deletion linode_api4/groups/lke.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def cluster_create(

result = self.client.post(
"/lke/clusters",
data=_flatten_request_body_recursive(drop_null_keys(params)),
data=drop_null_keys(_flatten_request_body_recursive(params)),
)

if "id" not in result:
Expand Down
40 changes: 40 additions & 0 deletions linode_api4/groups/object_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

from deprecated import deprecated

from linode_api4 import (
ObjectStorageEndpoint,
ObjectStorageEndpointType,
PaginatedList,
)
from linode_api4.errors import UnexpectedResponseError
from linode_api4.groups import Group
from linode_api4.objects import (
Expand Down Expand Up @@ -272,6 +277,30 @@ def transfer(self):

return MappedObject(**result)

def endpoints(self, *filters) -> PaginatedList:
"""
Returns a paginated list of all Object Storage endpoints available in your account.

This is intended to be called from the :any:`LinodeClient`
class, like this::

endpoints = client.object_storage.endpoints()

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-object-storage-endpoints

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
for more details on filtering.

:returns: A list of Object Storage Endpoints that matched the query.
:rtype: PaginatedList of ObjectStorageEndpoint
"""
return self.client._get_and_filter(
ObjectStorageEndpoint,
*filters,
endpoint="/object-storage/endpoints",
)

def buckets(self, *filters):
"""
Returns a paginated list of all Object Storage Buckets that you own.
Expand Down Expand Up @@ -299,6 +328,8 @@ def bucket_create(
label: str,
acl: ObjectStorageACL = ObjectStorageACL.PRIVATE,
cors_enabled=False,
s3_endpoint: Optional[str] = None,
endpoint_type: Optional[ObjectStorageEndpointType] = None,
):
"""
Creates an Object Storage Bucket in the specified cluster. Accounts with
Expand All @@ -320,6 +351,13 @@ def bucket_create(
should be created.
:type cluster: str

:param endpoint_type: The type of s3_endpoint available to the active user in this region.
:type endpoint_type: str
Enum: E0,E1,E2,E3

:param s3_endpoint: The active user's s3 endpoint URL, based on the endpoint_type and region.
:type s3_endpoint: str

:param cors_enabled: If true, the bucket will be created with CORS enabled for
all origins. For more fine-grained controls of CORS, use
the S3 API directly.
Expand All @@ -346,6 +384,8 @@ def bucket_create(
"label": label,
"acl": acl,
"cors_enabled": cors_enabled,
"s3_endpoint": s3_endpoint,
"endpoint_type": endpoint_type,
}

if self.is_cluster(cluster_or_region_id):
Expand Down
17 changes: 17 additions & 0 deletions linode_api4/objects/database.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from deprecated import deprecated

from linode_api4.objects import Base, DerivedBase, MappedObject, Property


Expand Down Expand Up @@ -63,6 +65,9 @@ def invalidate(self):
Base.invalidate(self)


@deprecated(
reason="Backups are not supported for non-legacy database clusters."
)
class DatabaseBackup(DerivedBase):
"""
A generic Managed Database backup.
Expand Down Expand Up @@ -97,6 +102,9 @@ def restore(self):
)


@deprecated(
reason="Backups are not supported for non-legacy database clusters."
)
class MySQLDatabaseBackup(DatabaseBackup):
"""
A backup for an accessible Managed MySQL Database.
Expand All @@ -107,6 +115,9 @@ class MySQLDatabaseBackup(DatabaseBackup):
api_endpoint = "/databases/mysql/instances/{database_id}/backups/{id}"


@deprecated(
reason="Backups are not supported for non-legacy database clusters."
)
class PostgreSQLDatabaseBackup(DatabaseBackup):
"""
A backup for an accessible Managed PostgreSQL Database.
Expand Down Expand Up @@ -221,6 +232,9 @@ def patch(self):
"{}/patch".format(MySQLDatabase.api_endpoint), model=self
)

@deprecated(
reason="Backups are not supported for non-legacy database clusters."
)
def backup_create(self, label, **kwargs):
"""
Creates a snapshot backup of a Managed MySQL Database.
Expand Down Expand Up @@ -358,6 +372,9 @@ def patch(self):
"{}/patch".format(PostgreSQLDatabase.api_endpoint), model=self
)

@deprecated(
reason="Backups are not supported for non-legacy database clusters."
)
def backup_create(self, label, **kwargs):
"""
Creates a snapshot backup of a Managed PostgreSQL Database.
Expand Down
13 changes: 2 additions & 11 deletions linode_api4/objects/lke.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
Region,
Type,
)
from linode_api4.util import drop_null_keys


class LKEType(Base):
Expand Down Expand Up @@ -79,8 +80,6 @@ class LKEClusterControlPlaneACLOptions(JSONObject):
"""
LKEClusterControlPlaneACLOptions is used to set
the ACL configuration of an LKE cluster's control plane.

NOTE: Control Plane ACLs may not currently be available to all users.
"""

enabled: Optional[bool] = None
Expand Down Expand Up @@ -116,8 +115,6 @@ class LKEClusterControlPlaneACL(JSONObject):
"""
LKEClusterControlPlaneACL describes the ACL configuration of an LKE cluster's
control plane.

NOTE: Control Plane ACLs may not currently be available to all users.
"""

include_none_values = True
Expand Down Expand Up @@ -337,8 +334,6 @@ def control_plane_acl(self) -> LKEClusterControlPlaneACL:
"""
Gets the ACL configuration of this cluster's control plane.

NOTE: Control Plane ACLs may not currently be available to all users.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-lke-cluster-acl

:returns: The cluster's control plane ACL configuration.
Expand Down Expand Up @@ -558,8 +553,6 @@ def control_plane_acl_update(
"""
Updates the ACL configuration for this cluster's control plane.

NOTE: Control Plane ACLs may not currently be available to all users.

API Documentation: https://techdocs.akamai.com/linode-api/reference/put-lke-cluster-acl

:param acl: The ACL configuration to apply to this cluster.
Expand All @@ -574,7 +567,7 @@ def control_plane_acl_update(
result = self._client.put(
f"{LKECluster.api_endpoint}/control_plane_acl",
model=self,
data={"acl": acl},
data={"acl": drop_null_keys(acl)},
)

acl = result.get("acl")
Expand All @@ -589,8 +582,6 @@ def control_plane_acl_delete(self):
This has the same effect as calling control_plane_acl_update with the `enabled` field
set to False. Access controls are disabled and all rules are deleted.

NOTE: Control Plane ACLs may not currently be available to all users.

API Documentation: https://techdocs.akamai.com/linode-api/reference/delete-lke-cluster-acl
"""
self._client.delete(
Expand Down
60 changes: 52 additions & 8 deletions linode_api4/objects/object_storage.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from dataclasses import dataclass
from typing import Optional
from urllib import parse

Expand All @@ -11,7 +12,7 @@
Property,
Region,
)
from linode_api4.objects.serializable import StrEnum
from linode_api4.objects.serializable import JSONObject, StrEnum
from linode_api4.util import drop_null_keys


Expand All @@ -28,6 +29,27 @@ class ObjectStorageKeyPermission(StrEnum):
READ_WRITE = "read_write"


class ObjectStorageEndpointType(StrEnum):
E0 = "E0"
E1 = "E1"
E2 = "E2"
E3 = "E3"


@dataclass
class ObjectStorageEndpoint(JSONObject):
"""
ObjectStorageEndpoint contains the core fields of an object storage endpoint object.

NOTE: This is not implemented as a typical API object (Base) because Object Storage Endpoints
cannot be refreshed, as there is no singular GET endpoint.
"""

region: str = ""
endpoint_type: ObjectStorageEndpointType = ""
s3_endpoint: Optional[str] = None


class ObjectStorageBucket(DerivedBase):
"""
A bucket where objects are stored in.
Expand All @@ -47,6 +69,8 @@ class ObjectStorageBucket(DerivedBase):
"label": Property(identifier=True),
"objects": Property(),
"size": Property(),
"endpoint_type": Property(),
"s3_endpoint": Property(),
}

@classmethod
Expand All @@ -63,13 +87,8 @@ def make_instance(cls, id, client, parent_id=None, json=None):
Override this method to pass in the parent_id from the _raw_json object
when it's available.
"""
if json is None:
return None

cluster_or_region = json.get("region") or json.get("cluster")

if parent_id is None and cluster_or_region:
parent_id = cluster_or_region
if json is not None:
parent_id = parent_id or json.get("region") or json.get("cluster")

if parent_id:
return super().make(id, client, cls, parent_id=parent_id, json=json)
Expand All @@ -78,6 +97,31 @@ def make_instance(cls, id, client, parent_id=None, json=None):
"Unexpected json response when making a new Object Storage Bucket instance."
)

def access_get(self):
"""
Returns a result object which wraps the current access config for this ObjectStorageBucket.

API Documentation: TODO

:returns: A result object which wraps the access that this ObjectStorageBucket is currently configured with.
:rtype: MappedObject
"""
result = self._client.get(
"{}/access".format(self.api_endpoint),
model=self,
)

if not any(
key in result
for key in ["acl", "acl_xml", "cors_enabled", "cors_xml"]
):
raise UnexpectedResponseError(
"Unexpected response when getting the bucket access config of a bucket!",
json=result,
)

return MappedObject(**result)

def access_modify(
self,
acl: Optional[ObjectStorageACL] = None,
Expand Down
4 changes: 3 additions & 1 deletion test/fixtures/object-storage_buckets_us-east-1.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"hostname": "example-bucket.us-east-1.linodeobjects.com",
"label": "example-bucket",
"objects": 4,
"size": 188318981
"size": 188318981,
"endpoint_type": "E1",
"s3_endpoint": "us-east-12.linodeobjects.com"
}
],
"page": 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
"hostname": "example-bucket.us-east-1.linodeobjects.com",
"label": "example-bucket",
"objects": 4,
"size": 188318981
"size": 188318981,
"endpoint_type": "E1",
"s3_endpoint": "us-east-12.linodeobjects.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"acl": "authenticated-read",
"acl_xml": "<AccessControlPolicy...",
"cors_enabled": true,
"cors_xml": "<CORSConfiguration>..."
}
Loading
Loading