Skip to content
104 changes: 104 additions & 0 deletions linode_api4/groups/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
MonitorService,
MonitorServiceToken,
)
from linode_api4.objects.filtering import and_
from linode_api4.objects.monitor import (
AkamaiObjectStorageLogsDestinationDetails,
ChannelDetails,
CustomHTTPSLogsDestinationDetails,
LogsStreamDetails,
)
Expand Down Expand Up @@ -423,6 +425,108 @@ def alert_definition_entities(
endpoint=endpoint,
)

def channel_create(
self,
label: str,
channel_type: str,
details: ChannelDetails,
) -> AlertChannel:
"""
Creates a new alert channel for the authenticated account.

An alert channel defines a notification destination (for example: an
email list) that can be associated with one or more alert definitions.
Currently only ``email`` is supported as a ``channel_type``.

API Documentation: https://techdocs.akamai.com/linode-api/reference/post-notification-channel

:param label: Human-readable name for the new alert channel.
:type label: str
:param channel_type: The type of notification channel (e.g. ``"email"``).
:type channel_type: str
:param details: Notification-type-specific configuration.
:type details: ChannelDetails

:returns: The newly created :class:`AlertChannel`.
:rtype: AlertChannel

.. note::
If you need to obtain a single :class:`AlertChannel`, use :meth:`LinodeClient.load`.
Example: ``client.load(AlertChannel, channel_id)``.
For updating an alert channel, use the ``save()`` method on the :class:`AlertChannel` object.
For deleting an alert channel, use the ``delete()`` method directly on the :class:`AlertChannel` object.
"""
params = {
"label": label,
"channel_type": channel_type,
"details": details.dict,
}

result = self.client.post("/monitor/alert-channels", data=params)

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

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

def alert_channel_alerts(self, channel_id: int, *filters) -> PaginatedList:
"""
Retrieve all alerts associated with a specific alert channel.

Returns a paginated collection of alert definitions associated with the
specified alert channel. This allows you to see which alert definitions
are configured to notify this specific channel.

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-notification-channel-alerts

:param channel_id: The ID of the alert channel to retrieve alerts for.
:type channel_id: int
:param filters: Optional filter expressions to apply to the collection.
See :doc:`Filtering Collections</linode_api4/objects/filtering>` for details.

:returns: A paginated list of alert definitions associated with this channel.
:rtype: PaginatedList[AlertDefinition]
"""
endpoint = f"/monitor/alert-channels/{channel_id}/alerts"

parsed_filters = None
if filters:
parsed_filters = (
and_(*filters).dct if len(filters) > 1 else filters[0].dct
)

response_json = self.client.get(endpoint, filters=parsed_filters)

if "data" not in response_json:
raise UnexpectedResponseError(
"Unexpected response when retrieving alert channel alerts!",
json=response_json,
)

result = [
AlertDefinition.make_instance(
obj["id"],
self.client,
parent_id=obj.get("service_type"),
json=obj,
)
for obj in response_json.get("data", [])
if "id" in obj
]

return PaginatedList(
Comment thread
mawasthy-lgtm marked this conversation as resolved.
self.client,
endpoint[1:],
page=result,
max_pages=response_json.get("pages", 1),
total_items=response_json.get("results", len(result)),
parent_id=None,
filters=parsed_filters,
)
Comment on lines +520 to +528

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem to be the right way of creating a PaginatedList instance. Does make_paginated_list or make_list work for your case?


def destinations(self, *filters) -> PaginatedList:
"""
List available logs destinations.
Expand Down
35 changes: 22 additions & 13 deletions linode_api4/objects/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
__all__ = [
"AggregateFunction",
"AlertChannel",
"AlertChannelType",
"AlertDefinition",
"AlertDefinitionChannel",
"AlertDefinitionEntity",
Expand Down Expand Up @@ -276,8 +277,8 @@ class MonitorDashboard(Base):
"id": Property(identifier=True),
"created": Property(is_datetime=True),
"label": Property(),
"service_type": Property(ServiceType),
"type": Property(DashboardType),
"service_type": Property(),
"type": Property(),
"group_by": Property(),
"widgets": Property(json_object=DashboardWidget),
"updated": Property(is_datetime=True),
Expand All @@ -294,7 +295,7 @@ class MonitorService(Base):
api_endpoint = "/monitor/services/{service_type}"
id_attribute = "service_type"
properties = {
"service_type": Property(ServiceType),
"service_type": Property(),
"label": Property(),
"alert": Property(json_object=ServiceAlert),
}
Expand Down Expand Up @@ -437,6 +438,15 @@ class AlertScope(StrEnum):
account = "account"


class AlertChannelType(StrEnum):
"""
Type values for alert channels.
"""

system = "system"
user = "user"


@dataclass
class AlertEntities(JSONObject):
"""
Expand Down Expand Up @@ -495,7 +505,7 @@ class AlertDefinition(DerivedBase):
"entity_ids": Property(mutable=True),
"description": Property(mutable=True),
"service_class": Property(alias_of="class"),
"scope": Property(AlertScope),
"scope": Property(),
"regions": Property(mutable=True),
"entities": Property(json_object=AlertEntities),
"channel_ids": Property(mutable=True),
Expand Down Expand Up @@ -541,25 +551,24 @@ class AlertChannel(Base):
"""
Represents an alert channel used to deliver notifications when alerts
fire. Alert channels define a destination and configuration for
notifications (for example: email lists, webhooks, PagerDuty, Slack, etc.).

API Documentation: https://techdocs.akamai.com/linode-api/reference/get-notification-channels
notifications (for example: email lists, webhooks, Slack, etc.).

This class maps to the Monitor API's `/monitor/alert-channels` resource
and is used by the SDK to list, load, and inspect channels.
API Documentation:
List/Get: https://techdocs.akamai.com/linode-api/reference/get-notification-channel
Create: https://techdocs.akamai.com/linode-api/reference/post-notification-channel

NOTE: Only read operations are supported for AlertChannel at this time.
Create, update, and delete (CRUD) operations are not allowed.
This class maps to the Monitor API's ``/monitor/alert-channels`` resource
and is used by the SDK to list, load, create, and inspect channels.
"""

api_endpoint = "/monitor/alert-channels/{id}"

properties = {
"id": Property(identifier=True),
"label": Property(),
"label": Property(mutable=True),
"type": Property(),
"channel_type": Property(),
"details": Property(mutable=False, json_object=ChannelDetails),
"details": Property(mutable=True, json_object=ChannelDetails),
"alerts": Property(mutable=False, json_object=AlertInfo),
"created": Property(is_datetime=True),
"updated": Property(is_datetime=True),
Expand Down
24 changes: 24 additions & 0 deletions test/fixtures/monitor_alert-channels_123.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"id": 123,
"label": "alert notification channel",
"type": "user",
"channel_type": "email",
"details": {
"email": {
"usernames": [
"admin-user1",
"admin-user2"
],
"recipient_type": "user"
}
},
"alerts": {
"url": "/monitor/alert-channels/123/alerts",
"type": "alerts-definitions",
"alert_count": 2
},
"created": "2024-01-01T00:00:00",
"updated": "2024-01-01T00:00:00",
"created_by": "tester",
"updated_by": "tester"
}
21 changes: 21 additions & 0 deletions test/fixtures/monitor_alert-channels_123_alerts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"data": [
{
"id": 12345,
"label": "DBAAS Alert 1",
"service_type": "dbaas",
"type": "alerts-definitions",
"url": "/monitor/services/dbaas/alerts-definitions/12345"
},
{
"id": 12346,
"label": "DBAAS Alert 2",
"service_type": "dbaas",
"type": "alerts-definitions",
"url": "/monitor/services/dbaas/alerts-definitions/12346"
}
],
"page": 1,
"pages": 1,
"results": 2
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"metric": "cpu_usage",
"operator": "gt",
"threshold": 90,
"unit": "percent"
"unit": "%"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"metric": "cpu_usage",
"operator": "gt",
"threshold": 90,
"unit": "percent"
"unit": "%"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"metric": "cpu_usage",
"metric_type": "gauge",
"scrape_interval": "60s",
"unit": "percent"
"unit": "%"
},
{
"available_aggregate_functions": [
Expand Down
Loading