Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
c77ec6d
TPT-3809: Added DiskEncryption field for LKE Node Pool creation (#670)
ezilber-akamai Mar 25, 2026
c9e18a5
TPT-4318: Add @linode/dx-sdets to CODEOWNERS (#671)
lgarber-akamai Mar 25, 2026
d692eef
TPT-4324: Allow dict passthrough for config_create 'devices' field; u…
lgarber-akamai Mar 30, 2026
47e620e
TPT-4298: Added PR title checking to lint workflow and clean up relea…
ezilber-akamai Apr 2, 2026
c3a77de
build(deps): bump actions/upload-artifact from 6 to 7 (#658)
dependabot[bot] Apr 7, 2026
fc2e33c
build(deps): bump slackapi/slack-github-action from 2.1.1 to 3 (#668)
dependabot[bot] Apr 7, 2026
02cd383
Remove content field from list alert channels response (#675)
shkaruna Apr 8, 2026
ecb5c3c
feat: add ACLP list entities method (#674)
shkaruna Apr 9, 2026
206a792
Cleanup block storage encryption LA notice (#655)
zliang-akamai Apr 13, 2026
c39c868
build(deps): bump pypa/gh-action-pypi-publish from 1.13.0 to 1.14.0 (…
dependabot[bot] Apr 16, 2026
9535d63
Use e2e firewall in all linode interface tests (#685)
zliang-akamai Apr 16, 2026
03c5f8c
Remove outdated note about Linode interfaces availability (#683)
zliang-akamai Apr 20, 2026
1a32329
TPT-4224: Add global quotas and quota usage support for OBJ services …
zliang-akamai May 4, 2026
4fec1e5
ACLP: Cleanup entity related response fields from alert definition (#…
shkaruna May 5, 2026
b690c4f
build(deps): bump actions/github-script from 8 to 9 (#682)
dependabot[bot] May 6, 2026
7bf9b4d
docs: update API documentation links in Lock classes (#679)
zliang-akamai May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,35 @@ on:
jobs:
lint:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
# Enforce TPT-1234: prefix on PR titles, with the following exemptions:
# - PRs labeled 'dependencies' (e.g. Dependabot PRs)
# - PRs labeled 'hotfix' (urgent fixes that may not have a ticket)
# - PRs labeled 'community-contribution' (external contributors without TPT tickets)
# - PRs labeled 'ignore-for-release' (release PRs that don't need a ticket prefix)
- name: Validate PR Title
if: github.event_name == 'pull_request'
uses: amannn/action-semantic-pull-request@v6
with:
types: |
TPT-\d+
requireScope: false
# Override the default header pattern to allow hyphens and digits in the type
# (e.g. "TPT-4298: Description"). The default pattern only matches word
# characters (\w) which excludes hyphens.
headerPattern: '^([\w-]+):\s?(.*)$'
headerPatternCorrespondence: type, subject
ignoreLabels: |
dependencies
hotfix
community-contribution
ignore-for-release
env:
GITHUB_TOKEN: ${{ github.token }}

- name: checkout repo
uses: actions/checkout@v6

Expand All @@ -31,7 +59,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/clean-release-notes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Clean Release Notes

on:
release:
types: [published]

jobs:
clean-release-notes:
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Remove ticket prefixes from release notes
uses: actions/github-script@v9
with:
script: |
const release = context.payload.release;

let body = release.body;

if (!body) {
console.log("Release body empty, nothing to clean.");
return;
}

// Remove ticket prefixes like "TPT-1234: " or "TPT-1234:"
body = body.replace(/TPT-\d+:\s*/g, '');

await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.id,
body: body
});

console.log("Release notes cleaned.");
2 changes: 1 addition & 1 deletion .github/workflows/e2e-test-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ jobs:
LINODE_CLI_OBJ_ACCESS_KEY: ${{ secrets.LINODE_CLI_OBJ_ACCESS_KEY }}
LINODE_CLI_OBJ_SECRET_KEY: ${{ secrets.LINODE_CLI_OBJ_SECRET_KEY }}

- uses: actions/github-script@v8
- uses: actions/github-script@v9
id: update-check-run
if: ${{ inputs.pull_request_number != '' && fromJson(steps.commit-hash.outputs.data).repository.pullRequest.headRef.target.oid == inputs.sha }}
env:
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ on:
- dev

env:
DEFAULT_PYTHON_VERSION: "3.10"
EOL_PYTHON_VERSION: "3.9"
DEFAULT_PYTHON_VERSION: "3.13"
EOL_PYTHON_VERSION: "3.10"
EXIT_STATUS: 0

jobs:
Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:

- name: Upload Test Report as Artifact
if: always()
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: test-report-file
if-no-files-found: ignore
Expand Down Expand Up @@ -241,7 +241,7 @@ jobs:
steps:
- name: Notify Slack
id: main_message
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down Expand Up @@ -273,7 +273,7 @@ jobs:

- name: Test summary thread
if: success()
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly-smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:

- name: Notify Slack
if: always() && github.repository == 'linode/linode_api4-python'
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-pypi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ jobs:
LINODE_SDK_VERSION: ${{ github.event.release.tag_name }}

- name: Publish the release artifacts to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # pin@release/v1.13.0
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # pin@release/v1.14.0
2 changes: 1 addition & 1 deletion .github/workflows/release-notify-slack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
steps:
- name: Notify Slack - Main Message
id: main_message
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down
3 changes: 1 addition & 2 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
* @linode/dx

* @linode/dx @linode/dx-sdets
1 change: 0 additions & 1 deletion linode_api4/groups/linode.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ def instance_create(
:param firewall: The firewall to attach this Linode to.
:type firewall: int or Firewall
:param disk_encryption: The disk encryption policy for this Linode.
NOTE: Disk encryption may not currently be available to all users.
:type disk_encryption: InstanceDiskEncryptionType or str
:param interfaces: An array of Network Interfaces to add to this Linode’s Configuration Profile.
At least one and up to three Interface objects can exist in this array.
Expand Down
4 changes: 2 additions & 2 deletions linode_api4/groups/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __call__(self, *filters):

locks = client.locks()

API Documentation: TBD
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-resource-locks

:param filters: Any number of filters to apply to this query.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
Expand All @@ -44,7 +44,7 @@ def create(
"""
Creates a new Resource Lock for the specified entity.

API Documentation: TBD
API Documentation: https://techdocs.akamai.com/linode-api/reference/post-resource-lock

:param entity_type: The type of entity to lock (e.g., "linode").
:type entity_type: str
Expand Down
56 changes: 52 additions & 4 deletions linode_api4/groups/monitor.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from typing import Any, Optional
from typing import Any, Optional, Union

from linode_api4 import PaginatedList
from linode_api4.errors import UnexpectedResponseError
from linode_api4.groups import Group
from linode_api4.objects import (
AlertChannel,
AlertDefinition,
AlertDefinitionEntity,
AlertScope,
MonitorDashboard,
MonitorMetricsDefinition,
MonitorService,
Expand Down Expand Up @@ -202,7 +204,7 @@ def alert_channels(self, *filters) -> PaginatedList:

.. note:: This endpoint is in beta and requires using the v4beta base URL.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-alert-channels
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-notification-channels

:param filters: Optional filter expressions to apply to the collection.
See :doc:`Filtering Collections</linode_api4/objects/filtering>` for details.
Expand All @@ -221,6 +223,8 @@ def create_alert_definition(
trigger_conditions: dict,
entity_ids: Optional[list[str]] = None,
description: Optional[str] = None,
scope: Optional[Union[AlertScope, str]] = None,
regions: Optional[list[str]] = None,
) -> AlertDefinition:
"""
Create a new alert definition for a given service type.
Expand Down Expand Up @@ -252,6 +256,10 @@ def create_alert_definition(
:type entity_ids: Optional[list[str]]
:param description: (Optional) Longer description for the alert definition.
:type description: Optional[str]
:param scope: (Optional) Alert scope (for example: `account`, `entity`, or `region`). Defaults to `entity`.
:type scope: Optional[Union[AlertScope, str]]
:param regions: (Optional) Regions to monitor.
:type regions: Optional[list[str]]

:returns: The newly created :class:`AlertDefinition`.
:rtype: AlertDefinition
Expand All @@ -267,10 +275,15 @@ def create_alert_definition(
"rule_criteria": rule_criteria,
"trigger_conditions": trigger_conditions,
}
if description is not None:
params["description"] = description

if entity_ids is not None:
params["entity_ids"] = entity_ids
if description is not None:
params["description"] = description
if scope is not None:
params["scope"] = scope
if regions is not None:
params["regions"] = regions

# API will validate service_type and return an error if missing
result = self.client.post(
Expand All @@ -284,3 +297,38 @@ def create_alert_definition(
)

return AlertDefinition(self.client, result["id"], service_type, result)

def alert_definition_entities(
self,
service_type: str,
id: int,
*filters,
) -> PaginatedList:
"""
List entities associated with a specific alert definition.

This endpoint supports pagination fields (`page`, `page_size`) in the API.

.. note:: This endpoint is in beta and requires using the v4beta base URL.

API Documentation: TODO

:param service_type: Service type for the alert definition (e.g. `dbaas`).
:type service_type: str
:param id: Alert definition identifier.
:type id: int
:param filters: Optional filter expressions to apply to the collection.
See :doc:`Filtering Collections</linode_api4/objects/filtering>`.

:returns: A paginated list of entities associated with the alert definition.
:rtype: PaginatedList[AlertDefinitionEntity]
"""

endpoint = (
f"/monitor/services/{service_type}/alert-definitions/{id}/entities"
)
return self.client._get_and_filter(
AlertDefinitionEntity,
*filters,
endpoint=endpoint,
)
16 changes: 16 additions & 0 deletions linode_api4/groups/object_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
ObjectStorageACL,
ObjectStorageBucket,
ObjectStorageCluster,
ObjectStorageGlobalQuota,
ObjectStorageKeyPermission,
ObjectStorageKeys,
ObjectStorageQuota,
Expand Down Expand Up @@ -533,3 +534,18 @@ def quotas(self, *filters):
:rtype: PaginatedList of ObjectStorageQuota
"""
return self.client._get_and_filter(ObjectStorageQuota, *filters)

def global_quotas(self, *filters):
"""
Lists the active account-level Object Storage quotas applied to your account.

API Documentation: TBD

: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 account-level Object Storage Quotas that matched the query.
:rtype: PaginatedList of ObjectStorageGlobalQuota
"""
return self.client._get_and_filter(ObjectStorageGlobalQuota, *filters)
1 change: 0 additions & 1 deletion linode_api4/groups/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ def create(self, label, region=None, linode=None, size=20, **kwargs):
:type tags: list[str]
:param encryption: Whether the new Volume should opt in or out of disk encryption.
:type encryption: str
Note: Block Storage Disk Encryption is not currently available to all users.
:returns: The new Volume.
:rtype: Volume
"""
Expand Down
Loading
Loading