Skip to content

Commit e6cc986

Browse files
Merge pull request #515 from linode/dev
v5.28.0
2 parents b93361f + f424bd2 commit e6cc986

16 files changed

+340
-60
lines changed

.github/workflows/e2e-test.yml

+28-4
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ jobs:
173173
runs-on: ubuntu-latest
174174
needs: [integration-tests]
175175
if: always() && github.repository == 'linode/linode_api4-python' # Run even if integration tests fail and only on main repository
176+
outputs:
177+
summary: ${{ steps.set-test-summary.outputs.summary }}
176178

177179
steps:
178180
- name: Checkout code
@@ -197,7 +199,6 @@ jobs:
197199
- name: Set release version env
198200
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
199201

200-
201202
- name: Add variables and upload test results
202203
if: always()
203204
run: |
@@ -213,12 +214,24 @@ jobs:
213214
LINODE_CLI_OBJ_ACCESS_KEY: ${{ secrets.LINODE_CLI_OBJ_ACCESS_KEY }}
214215
LINODE_CLI_OBJ_SECRET_KEY: ${{ secrets.LINODE_CLI_OBJ_SECRET_KEY }}
215216

217+
- name: Generate test summary and save to output
218+
id: set-test-summary
219+
run: |
220+
filename=$(ls | grep -E '^[0-9]{12}_sdk_test_report\.xml$')
221+
test_output=$(python3 e2e_scripts/tod_scripts/generate_test_summary.py "${filename}")
222+
{
223+
echo 'summary<<EOF'
224+
echo "$test_output"
225+
echo EOF
226+
} >> "$GITHUB_OUTPUT"
227+
216228
notify-slack:
217229
runs-on: ubuntu-latest
218-
needs: [integration-tests]
230+
needs: [integration-tests, process-upload-report]
219231
if: ${{ (success() || failure()) }} # Run even if integration tests fail and only on main repository
220232
steps:
221233
- name: Notify Slack
234+
id: main_message
222235
uses: slackapi/[email protected]
223236
with:
224237
method: chat.postMessage
@@ -229,7 +242,7 @@ jobs:
229242
- type: section
230243
text:
231244
type: mrkdwn
232-
text: ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:"
245+
text: ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* ${{ needs.integration-tests.result == 'success' && ':white_check_mark:' || ':failed:' }}"
233246
- type: divider
234247
- type: section
235248
fields:
@@ -247,4 +260,15 @@ jobs:
247260
- type: context
248261
elements:
249262
- type: mrkdwn
250-
text: "Triggered by: :bust_in_silhouette: `${{ github.actor }}`"
263+
text: "Triggered by: :bust_in_silhouette: `${{ github.actor }}`"
264+
265+
- name: Test summary thread
266+
if: success()
267+
uses: slackapi/[email protected]
268+
with:
269+
method: chat.postMessage
270+
token: ${{ secrets.SLACK_BOT_TOKEN }}
271+
payload: |
272+
channel: ${{ secrets.SLACK_CHANNEL_ID }}
273+
thread_ts: "${{ steps.main_message.outputs.ts }}"
274+
text: "${{ needs.process-upload-report.outputs.summary }}"

linode_api4/groups/account.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def settings(self):
101101
s = AccountSettings(self.client, result["managed"], result)
102102
return s
103103

104-
def invoices(self):
104+
def invoices(self, *filters):
105105
"""
106106
Returns Invoices issued to this account.
107107
@@ -112,9 +112,9 @@ def invoices(self):
112112
:returns: Invoices issued to this account.
113113
:rtype: PaginatedList of Invoice
114114
"""
115-
return self.client._get_and_filter(Invoice)
115+
return self.client._get_and_filter(Invoice, *filters)
116116

117-
def payments(self):
117+
def payments(self, *filters):
118118
"""
119119
Returns a list of Payments made on this account.
120120
@@ -123,7 +123,7 @@ def payments(self):
123123
:returns: A list of payments made on this account.
124124
:rtype: PaginatedList of Payment
125125
"""
126-
return self.client._get_and_filter(Payment)
126+
return self.client._get_and_filter(Payment, *filters)
127127

128128
def oauth_clients(self, *filters):
129129
"""
@@ -337,7 +337,7 @@ def add_promo_code(self, promo_code):
337337
json=resp,
338338
)
339339

340-
def service_transfers(self):
340+
def service_transfers(self, *filters):
341341
"""
342342
Returns a collection of all created and accepted Service Transfers for this account, regardless of the user that created or accepted the transfer.
343343
@@ -347,7 +347,7 @@ def service_transfers(self):
347347
:rtype: PaginatedList of ServiceTransfer
348348
"""
349349

350-
return self.client._get_and_filter(ServiceTransfer)
350+
return self.client._get_and_filter(ServiceTransfer, *filters)
351351

352352
def service_transfer_create(self, entities):
353353
"""

linode_api4/groups/lke.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def cluster_create(
131131

132132
result = self.client.post(
133133
"/lke/clusters",
134-
data=_flatten_request_body_recursive(drop_null_keys(params)),
134+
data=drop_null_keys(_flatten_request_body_recursive(params)),
135135
)
136136

137137
if "id" not in result:

linode_api4/groups/object_storage.py

+40
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
from deprecated import deprecated
77

8+
from linode_api4 import (
9+
ObjectStorageEndpoint,
10+
ObjectStorageEndpointType,
11+
PaginatedList,
12+
)
813
from linode_api4.errors import UnexpectedResponseError
914
from linode_api4.groups import Group
1015
from linode_api4.objects import (
@@ -272,6 +277,30 @@ def transfer(self):
272277

273278
return MappedObject(**result)
274279

280+
def endpoints(self, *filters) -> PaginatedList:
281+
"""
282+
Returns a paginated list of all Object Storage endpoints available in your account.
283+
284+
This is intended to be called from the :any:`LinodeClient`
285+
class, like this::
286+
287+
endpoints = client.object_storage.endpoints()
288+
289+
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-object-storage-endpoints
290+
291+
:param filters: Any number of filters to apply to this query.
292+
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
293+
for more details on filtering.
294+
295+
:returns: A list of Object Storage Endpoints that matched the query.
296+
:rtype: PaginatedList of ObjectStorageEndpoint
297+
"""
298+
return self.client._get_and_filter(
299+
ObjectStorageEndpoint,
300+
*filters,
301+
endpoint="/object-storage/endpoints",
302+
)
303+
275304
def buckets(self, *filters):
276305
"""
277306
Returns a paginated list of all Object Storage Buckets that you own.
@@ -299,6 +328,8 @@ def bucket_create(
299328
label: str,
300329
acl: ObjectStorageACL = ObjectStorageACL.PRIVATE,
301330
cors_enabled=False,
331+
s3_endpoint: Optional[str] = None,
332+
endpoint_type: Optional[ObjectStorageEndpointType] = None,
302333
):
303334
"""
304335
Creates an Object Storage Bucket in the specified cluster. Accounts with
@@ -320,6 +351,13 @@ def bucket_create(
320351
should be created.
321352
:type cluster: str
322353
354+
:param endpoint_type: The type of s3_endpoint available to the active user in this region.
355+
:type endpoint_type: str
356+
Enum: E0,E1,E2,E3
357+
358+
:param s3_endpoint: The active user's s3 endpoint URL, based on the endpoint_type and region.
359+
:type s3_endpoint: str
360+
323361
:param cors_enabled: If true, the bucket will be created with CORS enabled for
324362
all origins. For more fine-grained controls of CORS, use
325363
the S3 API directly.
@@ -346,6 +384,8 @@ def bucket_create(
346384
"label": label,
347385
"acl": acl,
348386
"cors_enabled": cors_enabled,
387+
"s3_endpoint": s3_endpoint,
388+
"endpoint_type": endpoint_type,
349389
}
350390

351391
if self.is_cluster(cluster_or_region_id):

linode_api4/objects/database.py

+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from deprecated import deprecated
2+
13
from linode_api4.objects import Base, DerivedBase, MappedObject, Property
24

35

@@ -63,6 +65,9 @@ def invalidate(self):
6365
Base.invalidate(self)
6466

6567

68+
@deprecated(
69+
reason="Backups are not supported for non-legacy database clusters."
70+
)
6671
class DatabaseBackup(DerivedBase):
6772
"""
6873
A generic Managed Database backup.
@@ -97,6 +102,9 @@ def restore(self):
97102
)
98103

99104

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

109117

118+
@deprecated(
119+
reason="Backups are not supported for non-legacy database clusters."
120+
)
110121
class PostgreSQLDatabaseBackup(DatabaseBackup):
111122
"""
112123
A backup for an accessible Managed PostgreSQL Database.
@@ -221,6 +232,9 @@ def patch(self):
221232
"{}/patch".format(MySQLDatabase.api_endpoint), model=self
222233
)
223234

235+
@deprecated(
236+
reason="Backups are not supported for non-legacy database clusters."
237+
)
224238
def backup_create(self, label, **kwargs):
225239
"""
226240
Creates a snapshot backup of a Managed MySQL Database.
@@ -358,6 +372,9 @@ def patch(self):
358372
"{}/patch".format(PostgreSQLDatabase.api_endpoint), model=self
359373
)
360374

375+
@deprecated(
376+
reason="Backups are not supported for non-legacy database clusters."
377+
)
361378
def backup_create(self, label, **kwargs):
362379
"""
363380
Creates a snapshot backup of a Managed PostgreSQL Database.

linode_api4/objects/lke.py

+2-11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
Region,
1515
Type,
1616
)
17+
from linode_api4.util import drop_null_keys
1718

1819

1920
class LKEType(Base):
@@ -79,8 +80,6 @@ class LKEClusterControlPlaneACLOptions(JSONObject):
7980
"""
8081
LKEClusterControlPlaneACLOptions is used to set
8182
the ACL configuration of an LKE cluster's control plane.
82-
83-
NOTE: Control Plane ACLs may not currently be available to all users.
8483
"""
8584

8685
enabled: Optional[bool] = None
@@ -116,8 +115,6 @@ class LKEClusterControlPlaneACL(JSONObject):
116115
"""
117116
LKEClusterControlPlaneACL describes the ACL configuration of an LKE cluster's
118117
control plane.
119-
120-
NOTE: Control Plane ACLs may not currently be available to all users.
121118
"""
122119

123120
include_none_values = True
@@ -337,8 +334,6 @@ def control_plane_acl(self) -> LKEClusterControlPlaneACL:
337334
"""
338335
Gets the ACL configuration of this cluster's control plane.
339336
340-
NOTE: Control Plane ACLs may not currently be available to all users.
341-
342337
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-lke-cluster-acl
343338
344339
:returns: The cluster's control plane ACL configuration.
@@ -558,8 +553,6 @@ def control_plane_acl_update(
558553
"""
559554
Updates the ACL configuration for this cluster's control plane.
560555
561-
NOTE: Control Plane ACLs may not currently be available to all users.
562-
563556
API Documentation: https://techdocs.akamai.com/linode-api/reference/put-lke-cluster-acl
564557
565558
:param acl: The ACL configuration to apply to this cluster.
@@ -574,7 +567,7 @@ def control_plane_acl_update(
574567
result = self._client.put(
575568
f"{LKECluster.api_endpoint}/control_plane_acl",
576569
model=self,
577-
data={"acl": acl},
570+
data={"acl": drop_null_keys(acl)},
578571
)
579572

580573
acl = result.get("acl")
@@ -589,8 +582,6 @@ def control_plane_acl_delete(self):
589582
This has the same effect as calling control_plane_acl_update with the `enabled` field
590583
set to False. Access controls are disabled and all rules are deleted.
591584
592-
NOTE: Control Plane ACLs may not currently be available to all users.
593-
594585
API Documentation: https://techdocs.akamai.com/linode-api/reference/delete-lke-cluster-acl
595586
"""
596587
self._client.delete(

0 commit comments

Comments
 (0)