Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
46 changes: 46 additions & 0 deletions linode_api4/groups/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from linode_api4.objects import (
AlertChannel,
AlertDefinition,
AlertDefinitionEntity,
MonitorDashboard,
MonitorMetricsDefinition,
MonitorService,
Expand Down Expand Up @@ -219,6 +220,8 @@ def create_alert_definition(
channel_ids: list[int],
rule_criteria: dict,
trigger_conditions: dict,
scope: Optional[str] = None,
regions: Optional[list[str]] = None,
entity_ids: Optional[list[str]] = None,
description: Optional[str] = None,
) -> AlertDefinition:
Expand Down Expand Up @@ -248,6 +251,10 @@ def create_alert_definition(
:param trigger_conditions: Trigger conditions that define when
the alert should transition state.
:type trigger_conditions: dict
:param scope: (Optional) Alert scope (for example: `account`, `entity`, or `region`). Defaults to `entity`.
:type scope: Optional[str]
:param regions: (Optional) Regions to monitor.
:type regions: Optional[list[str]]
:param entity_ids: (Optional) Restrict the alert to a subset of entity IDs.
:type entity_ids: Optional[list[str]]
:param description: (Optional) Longer description for the alert definition.
Expand All @@ -267,6 +274,10 @@ def create_alert_definition(
"rule_criteria": rule_criteria,
"trigger_conditions": trigger_conditions,
}
if scope is not None:
params["scope"] = scope
if regions is not None:
params["regions"] = regions
if description is not None:
params["description"] = description
if entity_ids is not None:
Expand All @@ -284,3 +295,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: add link to techdocs>

: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,
)
53 changes: 50 additions & 3 deletions linode_api4/objects/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"Alert",
"AlertChannel",
"AlertDefinition",
"AlertDefinitionEntity",
"AlertEntities",
"AlertScope",
"AlertType",
"Alerts",
"MonitorDashboard",
Expand Down Expand Up @@ -387,6 +390,43 @@ class AlertType(StrEnum):
user = "user"


class AlertScope(StrEnum):
"""
Scope values supported for alert definitions.
"""

entity = "entity"
region = "region"
account = "account"


@dataclass
class AlertEntities(JSONObject):
"""
Represents entity metadata for an alert definition.

For entity scoped alerts, `entities` envelope contains the URL to list entities,
a count, and a has_more_resources flag.
For region/account scoped alerts, the `entities` are returned as an empty object.
"""

url: str = ""
count: int = 0
has_more_resources: bool = False


@dataclass
class AlertDefinitionEntity(JSONObject):
"""
Represents an entity associated with an alert definition.
"""

id: str = ""
label: str = ""
url: str = ""
type: str = ""


class AlertDefinition(DerivedBase):
"""
Represents an alert definition for a monitor service.
Expand All @@ -406,17 +446,24 @@ class AlertDefinition(DerivedBase):
"severity": Property(mutable=True),
"type": Property(mutable=True),
"status": Property(mutable=True),
"has_more_resources": Property(mutable=True),
"scope": Property(AlertScope),
"regions": Property(mutable=True),
"has_more_resources": Property(
mutable=True
), # Deprecated; use entities.has_more_resources
"entities": Property(json_object=AlertEntities),
"rule_criteria": Property(mutable=True, json_object=RuleCriteria),
"trigger_conditions": Property(
mutable=True, json_object=TriggerConditions
),
"alert_channels": Property(mutable=True, json_object=Alerts),
"alert_channels": Property(mutable=True, json_object=Alert),
"created": Property(is_datetime=True),
"updated": Property(is_datetime=True),
"updated_by": Property(),
"created_by": Property(),
"entity_ids": Property(mutable=True),
"entity_ids": Property(
mutable=True
), # Deprecated; use entities.url to fetch associated entities
"description": Property(mutable=True),
"service_class": Property(alias_of="class"),
}
Expand Down
17 changes: 15 additions & 2 deletions test/fixtures/monitor_alert-definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,26 @@
"severity": 1,
"type": "user",
"description": "A test alert for dbaas service",
"scope": "entity",
"regions": [],
"entity_ids": ["13217"],
"alert_channels": [],
"entities": {
"url": "/monitor/services/dbaas/alert-definitions/12345/entities",
"count": 1,
"has_more_resources": false
},
"alert_channels": [
{
"id": 10000,
"label": "Read-Write Channel",
"type": "email",
"url": "/monitor/alert-channels/10000"
}
],
"has_more_resources": false,
"rule_criteria": null,
"trigger_conditions": null,
"class": "alert",
"notification_groups": [],
"status": "active",
"created": "2024-01-01T00:00:00",
"updated": "2024-01-01T00:00:00",
Expand Down
17 changes: 15 additions & 2 deletions test/fixtures/monitor_services_dbaas_alert-definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@
"severity": 1,
"type": "user",
"description": "A test alert for dbaas service",
"scope": "entity",
"regions": [],
"entity_ids": [
"13217"
],
"alert_channels": [],
"entities": {
"url": "/monitor/services/dbaas/alert-definitions/12345/entities",
"count": 1,
"has_more_resources": false
},
"alert_channels": [
{
"id": 10000,
"label": "Read-Write Channel",
"type": "email",
"url": "/monitor/alert-channels/10000"
}
],
"has_more_resources": false,
"rule_criteria": {
"rules": [
Expand Down Expand Up @@ -39,7 +53,6 @@
"trigger_occurrences": 3
},
"class": "alert",
"notification_groups": [],
"status": "active",
"created": "2024-01-01T00:00:00",
"updated": "2024-01-01T00:00:00",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,24 @@
"severity": 1,
"type": "user",
"description": "A test alert for dbaas service",
"scope": "entity",
"regions": [],
"entity_ids": [
"13217"
],
"alert_channels": [],
"entities": {
"url": "/monitor/services/dbaas/alert-definitions/12345/entities",
"count": 1,
"has_more_resources": false
},
"alert_channels": [
{
"id": 10000,
"label": "Read-Write Channel",
"type": "email",
"url": "/monitor/alert-channels/10000"
}
],
"has_more_resources": false,
"rule_criteria": {
"rules": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"data": [
{
"id": "1",
"label": "mydatabase-1",
"url": "/v4/databases/mysql/instances/1",
"type": "dbaas"
},
{
"id": "2",
"label": "mydatabase-2",
"url": "/v4/databases/mysql/instances/2",
"type": "dbaas"
},
{
"id": "3",
"label": "mydatabase-3",
"url": "/v4/databases/mysql/instances/3",
"type": "dbaas"
}
],
"page": 1,
"pages": 1,
"results": 3
}
35 changes: 34 additions & 1 deletion test/integration/models/monitor/test_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

import pytest

from linode_api4 import LinodeClient
from linode_api4 import LinodeClient, PaginatedList
from linode_api4.objects import (
AlertDefinition,
AlertDefinitionEntity,
ApiError,
MonitorDashboard,
MonitorMetricsDefinition,
Expand Down Expand Up @@ -275,3 +276,35 @@ def wait_for_alert_ready(alert_id, service_type: str):
AlertDefinition, created.id, service_type
)
delete_alert.delete()


def test_alert_definition_entities(test_linode_client):
"""Test listing entities associated with an alert definition.

This test first retrieves alert definitions for a service type, then lists entities for the first alert definition.
It asserts that the returned entities have expected fields.
"""
pytest.skip("reason: list alert_definition_entities API is not yet live")
client = test_linode_client
service_type = "dbaas"

alert_definitions = client.monitor.alert_definitions(
service_type=service_type
)

if len(alert_definitions) == 0:
pytest.skip("No alert definitions available for dbaas service type")

alert_def = alert_definitions[0]
entities = client.monitor.alert_definition_entities(
service_type, alert_def.id
)

assert isinstance(entities, PaginatedList)
if len(entities) > 0:
entity = entities[0]
assert isinstance(entity, AlertDefinitionEntity)
assert entity.id
assert entity.label
assert entity.url
assert entity.type == service_type
Loading