Skip to content

Commit c29a060

Browse files
committed
adding monitors in region endpoint
1 parent f2055c6 commit c29a060

8 files changed

Lines changed: 117 additions & 11 deletions

File tree

linode_api4/objects/monitor.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class ServiceType(StrEnum):
4949
firewall = "firewall"
5050
object_storage = "object_storage"
5151
aclb = "aclb"
52+
netloadbalancer = "netloadbalancer"
5253

5354

5455
class MetricType(StrEnum):
@@ -82,6 +83,10 @@ class MetricUnit(StrEnum):
8283
RATIO = "ratio"
8384
OPS_PER_SECOND = "ops_per_second"
8485
IOPS = "iops"
86+
KILO_BYTES_PER_SECOND = "kilo_bytes_per_second"
87+
SESSIONS_PER_SECOND = "sessions_per_second"
88+
PACKETS_PER_SECOND = "packets_per_second"
89+
KILO_BITS_PER_SECOND = "kilo_bits_per_second"
8590

8691

8792
class DashboardType(StrEnum):
@@ -93,6 +98,17 @@ class DashboardType(StrEnum):
9398
custom = "custom"
9499

95100

101+
@dataclass
102+
class Filter(JSONObject):
103+
"""
104+
Represents a filter in the filters list of a dashboard widget.
105+
"""
106+
107+
dimension_label: str = ""
108+
operator: str = ""
109+
value: str = ""
110+
111+
96112
@dataclass
97113
class DashboardWidget(JSONObject):
98114
"""
@@ -107,6 +123,19 @@ class DashboardWidget(JSONObject):
107123
chart_type: ChartType = ""
108124
y_label: str = ""
109125
aggregate_function: AggregateFunction = ""
126+
group_by: List[str] = field(default_factory=list)
127+
filters: Optional[List[Filter]] = None
128+
129+
130+
@dataclass
131+
class ServiceAlert(JSONObject):
132+
"""
133+
Represents alert configuration options for a monitor service.
134+
"""
135+
136+
polling_interval_seconds: List[int] = field(default_factory=list)
137+
evaluation_period_seconds: List[int] = field(default_factory=list)
138+
scope: List[str] = field(default_factory=list)
110139

111140

112141
@dataclass
@@ -154,7 +183,7 @@ class MonitorDashboard(Base):
154183
"label": Property(),
155184
"service_type": Property(ServiceType),
156185
"type": Property(DashboardType),
157-
"widgets": Property(List[DashboardWidget]),
186+
"widgets": Property(json_object=DashboardWidget),
158187
"updated": Property(is_datetime=True),
159188
}
160189

@@ -171,6 +200,7 @@ class MonitorService(Base):
171200
properties = {
172201
"service_type": Property(ServiceType),
173202
"label": Property(),
203+
"alert": Property(json_object=ServiceAlert),
174204
}
175205

176206

linode_api4/objects/region.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,24 @@ class RegionPlacementGroupLimits(JSONObject):
1616
maximum_linodes_per_pg: int = 0
1717

1818

19+
@dataclass
20+
class RegionMonitors(JSONObject):
21+
"""
22+
Represents the monitor services available in a region.
23+
Lists the services in this region that support metrics and alerts
24+
use with Akamai Cloud Pulse (ACLP).
25+
"""
26+
27+
alerts: list[str] | None = None
28+
metrics: list[str] | None = None
29+
30+
def __post_init__(self):
31+
if self.alerts is None:
32+
self.alerts = []
33+
if self.metrics is None:
34+
self.metrics = []
35+
36+
1937
class Region(Base):
2038
"""
2139
A Region. Regions correspond to individual data centers, each located in a different geographical area.
@@ -35,6 +53,7 @@ class Region(Base):
3553
"placement_group_limits": Property(
3654
json_object=RegionPlacementGroupLimits
3755
),
56+
"monitors": Property(json_object=RegionMonitors),
3857
}
3958

4059
@property

test/fixtures/monitor_dashboards.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
"metric": "cpu_usage",
1717
"size": 12,
1818
"unit": "%",
19-
"y_label": "cpu_usage"
19+
"y_label": "cpu_usage",
20+
"group_by": ["entity_id"],
21+
"filters": null
2022
},
2123
{
2224
"aggregate_function": "sum",
@@ -26,7 +28,9 @@
2628
"metric": "write_iops",
2729
"size": 6,
2830
"unit": "IOPS",
29-
"y_label": "write_iops"
31+
"y_label": "write_iops",
32+
"group_by": ["entity_id"],
33+
"filters": null
3034
}
3135
]
3236
}

test/fixtures/monitor_dashboards_1.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"metric": "cpu_usage",
1515
"size": 12,
1616
"unit": "%",
17-
"y_label": "cpu_usage"
17+
"y_label": "cpu_usage",
18+
"group_by": ["entity_id"],
19+
"filters": null
1820
},
1921
{
2022
"aggregate_function": "sum",
@@ -24,7 +26,9 @@
2426
"metric": "available_memory",
2527
"size": 6,
2628
"unit": "GB",
27-
"y_label": "available_memory"
29+
"y_label": "available_memory",
30+
"group_by": ["entity_id"],
31+
"filters": null
2832
}
2933
]
3034
}

test/fixtures/monitor_services_dbaas_dashboards.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
"metric": "cpu_usage",
1717
"size": 12,
1818
"unit": "%",
19-
"y_label": "cpu_usage"
19+
"y_label": "cpu_usage",
20+
"group_by": ["entity_id"],
21+
"filters": null
2022
},
2123
{
2224
"aggregate_function": "sum",
@@ -26,7 +28,16 @@
2628
"metric": "memory_usage",
2729
"size": 6,
2830
"unit": "%",
29-
"y_label": "memory_usage"
31+
"y_label": "memory_usage",
32+
"group_by": ["entity_id"],
33+
"filters": [
34+
{
35+
"dimension_label": "pattern",
36+
"operator": "in",
37+
"value": "publicout,privateout"
38+
}
39+
]
40+
3041
}
3142
]
3243
}

test/fixtures/regions.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,14 @@
125125
"Block Storage",
126126
"Object Storage"
127127
],
128+
"monitors": {
129+
"alerts": [
130+
"Managed Databases"
131+
],
132+
"metrics": [
133+
"Managed Databases"
134+
]
135+
},
128136
"status": "ok",
129137
"resolvers": {
130138
"ipv4": "66.228.42.5,96.126.106.5,50.116.53.5,50.116.58.5,50.116.61.5,50.116.62.5,66.175.211.5,97.107.133.4,207.192.69.4,207.192.69.5",

test/unit/objects/monitor_test.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ def test_dashboard_by_ID(self):
4141
self.assertEqual(dashboard.widgets[0].size, 12)
4242
self.assertEqual(dashboard.widgets[0].unit, "%")
4343
self.assertEqual(dashboard.widgets[0].y_label, "cpu_usage")
44+
self.assertEqual(dashboard.widgets[0].group_by, ["entity_id"])
45+
self.assertIsNone(dashboard.widgets[0].filters)
4446

4547
def test_dashboard_by_service_type(self):
4648
dashboards = self.client.monitor.dashboards(service_type="dbaas")
@@ -62,6 +64,21 @@ def test_dashboard_by_service_type(self):
6264
self.assertEqual(dashboards[0].widgets[0].size, 12)
6365
self.assertEqual(dashboards[0].widgets[0].unit, "%")
6466
self.assertEqual(dashboards[0].widgets[0].y_label, "cpu_usage")
67+
self.assertEqual(dashboards[0].widgets[0].group_by, ["entity_id"])
68+
self.assertIsNone(dashboards[0].widgets[0].filters)
69+
70+
# Test the second widget which has filters
71+
self.assertEqual(dashboards[0].widgets[1].label, "Memory Usage")
72+
self.assertEqual(dashboards[0].widgets[1].group_by, ["entity_id"])
73+
self.assertIsNotNone(dashboards[0].widgets[1].filters)
74+
self.assertEqual(len(dashboards[0].widgets[1].filters), 1)
75+
self.assertEqual(
76+
dashboards[0].widgets[1].filters[0].dimension_label, "pattern"
77+
)
78+
self.assertEqual(dashboards[0].widgets[1].filters[0].operator, "in")
79+
self.assertEqual(
80+
dashboards[0].widgets[1].filters[0].value, "publicout,privateout"
81+
)
6582

6683
def test_get_all_dashboards(self):
6784
dashboards = self.client.monitor.dashboards()
@@ -83,29 +100,37 @@ def test_get_all_dashboards(self):
83100
self.assertEqual(dashboards[0].widgets[0].size, 12)
84101
self.assertEqual(dashboards[0].widgets[0].unit, "%")
85102
self.assertEqual(dashboards[0].widgets[0].y_label, "cpu_usage")
103+
self.assertEqual(dashboards[0].widgets[0].group_by, ["entity_id"])
104+
self.assertIsNone(dashboards[0].widgets[0].filters)
86105

87106
def test_specific_service_details(self):
88107
data = self.client.load(MonitorService, "dbaas")
89108
self.assertEqual(data.label, "Databases")
90109
self.assertEqual(data.service_type, "dbaas")
91110

111+
# Test alert configuration
112+
self.assertIsNotNone(data.alert)
113+
self.assertEqual(data.alert.polling_interval_seconds, [300])
114+
self.assertEqual(data.alert.evaluation_period_seconds, [300])
115+
self.assertEqual(data.alert.scope, ["entity"])
116+
92117
def test_metric_definitions(self):
93118

94119
metrics = self.client.monitor.metric_definitions(service_type="dbaas")
95120
self.assertEqual(
96121
metrics[0].available_aggregate_functions,
97122
["max", "avg", "min", "sum"],
98123
)
99-
self.assertEqual(metrics[0].is_alertable, True)
124+
self.assertTrue(metrics[0].is_alertable)
100125
self.assertEqual(metrics[0].label, "CPU Usage")
101126
self.assertEqual(metrics[0].metric, "cpu_usage")
102127
self.assertEqual(metrics[0].metric_type, "gauge")
103128
self.assertEqual(metrics[0].scrape_interval, "60s")
104129
self.assertEqual(metrics[0].unit, "percent")
105-
self.assertEqual(metrics[0].dimensions[0].dimension_label, "node_type")
106-
self.assertEqual(metrics[0].dimensions[0].label, "Node Type")
130+
self.assertEqual(metrics[0].dimensions[0]["dimension_label"], "node_type")
131+
self.assertEqual(metrics[0].dimensions[0]["label"], "Node Type")
107132
self.assertEqual(
108-
metrics[0].dimensions[0].values, ["primary", "secondary"]
133+
metrics[0].dimensions[0]["values"], ["primary", "secondary"]
109134
)
110135

111136
def test_create_token(self):

test/unit/objects/region_test.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ def test_get_region(self):
2828
region.placement_group_limits.maximum_linodes_per_pg, 5
2929
)
3030

31+
# Test monitors section
32+
self.assertIsNotNone(region.monitors)
33+
self.assertEqual(region.monitors.alerts, ["Managed Databases"])
34+
self.assertEqual(region.monitors.metrics, ["Managed Databases"])
35+
3136
def test_region_availability(self):
3237
"""
3338
Tests that availability for a specific region can be listed and filtered on.

0 commit comments

Comments
 (0)