Skip to content
Draft
95 changes: 95 additions & 0 deletions linode_api4/groups/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ def create_alert_definition(
description: Optional[str] = None,
scope: Optional[Union[AlertScope, str]] = None,
regions: Optional[list[str]] = None,
group_by: Optional[list[str]] = None,
) -> AlertDefinition:
"""
Create a new alert definition for a given service type.
Expand Down Expand Up @@ -270,6 +271,8 @@ def create_alert_definition(
:type scope: Optional[Union[AlertScope, str]]
:param regions: (Optional) Regions to monitor.
:type regions: Optional[list[str]]
:param group_by: (Optional) Aggregates metric data by dimension so that alert conditions are evaluated independently for each dimension value.
:type group_by: Optional[list[str]]

:returns: The newly created :class:`AlertDefinition`.
:rtype: AlertDefinition
Expand All @@ -294,6 +297,8 @@ def create_alert_definition(
params["scope"] = scope
if regions is not None:
params["regions"] = regions
if group_by is not None:
params["group_by"] = group_by

# API will validate service_type and return an error if missing
result = self.client.post(
Expand All @@ -308,6 +313,96 @@ def create_alert_definition(

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

def clone_alert_definition(
self,
service_type: str,
id: int,
label: str,
description: Optional[str] = None,
scope: Optional[Union[AlertScope, str]] = None,
regions: Optional[list[str]] = None,
entity_ids: Optional[list[str]] = None,
severity: Optional[int] = None,
rule_criteria: Optional[dict] = None,
trigger_conditions: Optional[dict] = None,
channel_ids: Optional[list[int]] = None,
group_by: Optional[list[str]] = None,
) -> AlertDefinition:
"""
Clone an existing alert definition for a given service type.
The clone request creates a new alert definition based on the source
definition identified by ``id``.

API URL: POST /monitor/services/{service_type}/alert-definitions/{id}/clone
API Documentation: TODO

:param service_type: Service type for the source alert definition
(e.g. ``"dbaas"``).
:type service_type: str
:param id: Source alert definition identifier.
:type id: int (Alert identifier)
:param label: Human-readable label for the cloned alert definition.
This value is mandatory and must be unique.
:type label: str
:param description: (Optional) Longer description for the cloned alert definition.
:type description: Optional[str]
:param scope: (Optional) Alert scope provided in the clone request.
Scope is inherited from the source alert and is immutable.
:type scope: Optional[Union[AlertScope, 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 severity: (Optional) Severity level for the alert.
:type severity: Optional[int]
:param rule_criteria: (Optional) Rule criteria used to evaluate the alert.
:type rule_criteria: Optional[dict]
:param trigger_conditions: (Optional) Trigger conditions for alert state transitions.
:type trigger_conditions: Optional[dict]
:param channel_ids: (Optional) List of alert channel IDs to notify.
:type channel_ids: Optional[list[int]]
:param group_by: (Optional) Aggregates metric data by dimension so that alert conditions are evaluated independently for each dimension value.
:type group_by: Optional[list[str]]

:returns: The newly created cloned :class:`AlertDefinition`.
:rtype: AlertDefinition
"""
params = {
"label": label,
}

if description is not None:
params["description"] = description
if scope is not None:
params["scope"] = scope
if regions is not None:
params["regions"] = regions
if entity_ids is not None:
params["entity_ids"] = entity_ids
if severity is not None:
params["severity"] = severity
if rule_criteria is not None:
params["rule_criteria"] = rule_criteria
if trigger_conditions is not None:
params["trigger_conditions"] = trigger_conditions
if channel_ids is not None:
params["channel_ids"] = channel_ids
if group_by is not None:
params["group_by"] = group_by

result = self.client.post(
f"/monitor/services/{service_type}/alert-definitions/{id}/clone",
data=params,
)

if "id" not in result:
raise UnexpectedResponseError(
"Unexpected response when cloning alert definition!",
json=result,
)

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

def alert_definition_entities(
self,
service_type: str,
Expand Down
1 change: 1 addition & 0 deletions linode_api4/objects/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ class AlertDefinition(DerivedBase):
"regions": Property(mutable=True),
"entities": Property(json_object=AlertEntities),
"channel_ids": Property(mutable=True),
"group_by": Property(mutable=True),
}


Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/monitor_alert-definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"description": "A test alert for dbaas service",
"scope": "entity",
"regions": [],
"group_by": [
"entity_id"
],
"entities": {
"url": "/monitor/services/dbaas/alert-definitions/12345/entities",
"count": 1,
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/monitor_services_dbaas_alert-definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"description": "A test alert for dbaas service",
"scope": "entity",
"regions": [],
"group_by": [
"entity_id"
],
"entities": {
"url": "/monitor/services/dbaas/alert-definitions/12345/entities",
"count": 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"description": "A test alert for dbaas service",
"scope": "entity",
"regions": [],
"group_by": [
"entity_id"
],
"entities": {
"url": "/monitor/services/dbaas/alert-definitions/12345/entities",
"count": 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"id": 67891,
"label": "Cloned Alert",
"service_type": "dbaas",
"severity": 1,
"type": "user",
"description": "Cloned from source alert",
"scope": "entity",
"regions": [],
"group_by": [
"entity_id"
],
"entities": {
"url": "/monitor/services/dbaas/alert-definitions/67891/entities",
"count": 1,
"has_more_resources": false
},
"alert_channels": [
{
"id": 10000,
"label": "Read-Write Channel",
"type": "email",
"url": "/monitor/alert-channels/10000"
}
],
"rule_criteria": {
"rules": [
{
"aggregate_function": "avg",
"dimension_filters": [
{
"dimension_label": "node_type",
"label": "Node Type",
"operator": "eq",
"value": "primary"
}
],
"label": "High CPU Usage",
"metric": "cpu_usage",
"operator": "gt",
"threshold": 90,
"unit": "percent"
}
]
},
"trigger_conditions": {
"criteria_condition": "ALL",
"evaluation_period_seconds": 300,
"polling_interval_seconds": 60,
"trigger_occurrences": 3
},
"class": "alert",
"status": "active",
"created": "2024-01-01T00:00:00",
"updated": "2024-01-01T00:00:00",
"updated_by": "tester"
}
Loading