Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
1928388
Add Resource Alerts Plugin with DAO, VO, and API Responses
Damans227 Jun 12, 2026
444de69
Implement Resource Alerts Manager and related components
Damans227 Jun 16, 2026
7f22b13
Add unit tests for Resource Alerts functionality
Damans227 Jun 16, 2026
8ca6ffb
Implement email notification feature in Resource Alert Manager
Damans227 Jun 22, 2026
e540d85
Refactor ResourceAlertManagerImpl to extract publishAlertEvent method…
Damans227 Jun 22, 2026
6ff6056
Add Resource Alerts functionality with UI components and localization
Damans227 Jun 23, 2026
a799f62
Implement resource alert rules limit and enhance evaluation logic for…
Damans227 Jun 23, 2026
fb5426b
Change alert icon from AlertOutlined to BellOutlined in resource aler…
Damans227 Jun 23, 2026
9fdc078
Add resource alert rule grouping functionality in configuration
Damans227 Jun 23, 2026
2b1b275
Add '/resourcealertrule' endpoint to path matching in ListView component
Damans227 Jun 23, 2026
3a2cb18
Add scoped styles for form component in CreateResourceAlertRule
Damans227 Jun 23, 2026
ee3b6b8
Refactor email configuration handling and improve error logging in Re…
Damans227 Jun 24, 2026
4af430a
Add monitoring section and update resource alert labels in localization
Damans227 Jun 24, 2026
810a216
Update icon for monitoring section to BarChartOutlined
Damans227 Jun 24, 2026
07c4c42
Rename resource alert settings to design names and add default repeat…
Damans227 Sep 23, 2026
e18061b
Use resource UUIDs in resource alert APIs and pass resource type from…
Damans227 Sep 23, 2026
34fab8b
Add access checks to resource alert APIs and open them to domain admi…
Damans227 Sep 23, 2026
78b4904
Allow delivering alert payloads directly to selected webhooks
Damans227 Sep 23, 2026
8719d97
Add table, VO and DAO to map resource alert rules to webhooks
Damans227 Sep 23, 2026
ff5e9a1
Add webhookids to create and update resource alert rule APIs
Damans227 Sep 23, 2026
a6599b9
Deliver fired resource alerts to the rule's webhooks as JSON
Damans227 Sep 23, 2026
5085656
Log resource alert evaluation failures instead of ignoring them
Damans227 Sep 23, 2026
10ac5cc
Add webhook selection to resource alert rule forms in UI
Damans227 Sep 23, 2026
f7f6217
Add host load average and host network metrics to resource alerts
Damans227 Sep 23, 2026
0650ab0
Add volume size metric to resource alerts
Damans227 Sep 23, 2026
c045f36
Add storage pool used IOPS metric to resource alerts
Damans227 Sep 23, 2026
9ba2ec0
Target resource alerts at 24.0.0 after rebase
Damans227 Sep 23, 2026
5a8b9ba
Scope generic resource alert rules by owner role: whole cloud, domain…
Damans227 Sep 23, 2026
cf06166
Evaluate resource alert rules on a single management server
Damans227 Sep 23, 2026
26ef53e
Remove old fired resource alerts and page listResourceAlerts
Damans227 Sep 23, 2026
4711cc9
Remove resource alert rules whose owner or resource no longer exists
Damans227 Sep 23, 2026
93f195b
Record audit events for resource alert rule create, update and delete
Damans227 Sep 23, 2026
482328f
Move resource alert commands to the user package and use ApiConstants…
Damans227 Sep 23, 2026
c087d42
Validate resource alert rule thresholds and reset interval
Damans227 Sep 23, 2026
589c437
Apply webhook delivery security settings to alert deliveries
Damans227 Sep 23, 2026
fa03083
Log alert webhook deliveries that fail inside the delivery thread
Damans227 Sep 23, 2026
55b7b04
Return resource name in resource alert rule and alert responses
Damans227 Sep 24, 2026
ae69c27
Add resource and owner pickers to resource alert form and show resour…
Damans227 Sep 24, 2026
e35514c
Round metric values in resource alert tables
Damans227 Sep 24, 2026
5b5177d
Show resource name and UUID in alert email and event bus messages
Damans227 Sep 28, 2026
2eab0db
Show webhook names on resource alert rules
Damans227 Sep 28, 2026
21b85e0
Record webhook deliveries for resource alerts
Damans227 Sep 28, 2026
ca16226
Show All resources for generic rules in the rule list
Damans227 Sep 28, 2026
3a54751
Keep proper API error codes for resource alert rule commands
Sep 29, 2026
cee93ee
Fall back to the default when the resource alert evaluation interval …
Sep 29, 2026
21c591b
Only let a rule override all-resources rules of the same owner
Sep 29, 2026
6968a0d
Remove alert history when a resource alert rule is removed
Sep 29, 2026
8282f23
Add rule owner account and domain to resource alert email and event b…
Sep 29, 2026
01f4082
Hide empty webhooks on rule details and hint the default cooldown
Sep 29, 2026
405361d
Add Marvin smoke tests for resource alerts
Sep 29, 2026
05fe3bd
Run resource alerts smoke tests in CI
Sep 29, 2026
88afc8f
Skip resources that are stopped or out of service when checking resou…
Sep 29, 2026
41a3e15
Remove resource alert rules whose owner lost access to the resource
Sep 29, 2026
9c710a7
Support projects for resource alert rules
Sep 29, 2026
c2194b9
Custom edit form for resource alert rules that keeps current webhooks
Sep 29, 2026
50e32a4
Skip volume disk metrics when the attached VM is not running
Sep 29, 2026
f94b96c
Add indexes for resource alert lookups
Damans227 Sep 30, 2026
f58de91
Read only the newest recent VM stats when checking resource alert rules
Damans227 Sep 30, 2026
0406c21
Keep disk IO metrics on Instances only, not Volumes
Damans227 Sep 30, 2026
9f45fbe
Send resource alert emails from one thread with a bounded queue
Damans227 Sep 30, 2026
2302c5f
Drop deleted webhooks from resource alert rules
Damans227 Sep 30, 2026
3ea7fe8
Page and filter resource alerts on the server in alert tabs
Damans227 Sep 30, 2026
f9be1a8
Reject blank and duplicate resource alert rule names
Damans227 Sep 30, 2026
0a9a73c
Allow resource alert messages up to the stored length of 4096
Damans227 Sep 30, 2026
b9af56d
Pick the resource alert type filter from a list and accept any case i…
Damans227 Sep 30, 2026
61c43e7
Filter fired resource alerts by rule name keyword and reject unknown …
Damans227 Sep 30, 2026
f3431d0
Check the resource alert rule limit and name under a per-account lock
Damans227 Sep 30, 2026
6ab4f3b
Log fired resource alerts at info level
Damans227 Sep 30, 2026
0e044f4
Keep checking other resource alert rules when one rule fails
Damans227 Sep 30, 2026
70fa2bf
Allow a few seconds of slack when checking the resource alert cooldown
Damans227 Sep 30, 2026
6a1fc1e
Log at info when an alert skips a disabled or filtered webhook
Damans227 Sep 30, 2026
a8a5190
Rename the volume size metric to volume used and add volume used percent
Damans227 Sep 30, 2026
59d31f1
Show friendly labels for resource alert rule types, metrics, conditio…
Damans227 Sep 30, 2026
cc9d31b
Leave system VM and router volumes out of all-volumes resource alert …
Damans227 Sep 30, 2026
cafdc78
Fix bulk delete of resource alert rules and say the history goes too
Damans227 Sep 30, 2026
100355d
Let resource alert rules be disabled and enabled again
Damans227 Sep 30, 2026
4be82e3
rename resource alert configs to resource.alert.*
Damans227 Oct 6, 2026
8476b1f
use -1 for unlimited in resource alert settings
Damans227 Oct 8, 2026
183a671
drop duplicate label.message after rebase
Damans227 Oct 8, 2026
7a45655
Hide extension VMs and hosts from resource alert rules
Damans227 Oct 9, 2026
675d5c1
Move resource alerts from a plugin into core next to the existing ale…
Damans227 Oct 13, 2026
0d498d2
Load the rule fresh in the resource alert edit form so list labels ar…
Damans227 Oct 13, 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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ jobs:
smoke/test_nested_virtualization
smoke/test_set_sourcenat
smoke/test_webhook_lifecycle
smoke/test_resource_alerts
smoke/test_purge_expunged_vms
smoke/test_extension_lifecycle
smoke/test_extension_custom_action_lifecycle
Expand Down
33 changes: 33 additions & 0 deletions api/src/main/java/com/cloud/alert/AlertCondition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package com.cloud.alert;

public enum AlertCondition {
GT, GTE, LT, LTE, EQ;

public boolean evaluate(double value, double threshold) {
switch (this) {
case GT: return value > threshold;
case GTE: return value >= threshold;
case LT: return value < threshold;
case LTE: return value <= threshold;
case EQ: return Double.compare(value, threshold) == 0;
default: return false;
}
}
}
22 changes: 22 additions & 0 deletions api/src/main/java/com/cloud/alert/AlertSeverity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package com.cloud.alert;

public enum AlertSeverity {
CRITICAL, HIGH, MEDIUM, LOW
}
34 changes: 34 additions & 0 deletions api/src/main/java/com/cloud/alert/ResourceAlert.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package com.cloud.alert;

import java.util.Date;

import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;

public interface ResourceAlert extends Identity, InternalIdentity {

long getAlertRuleId();
Long getResourceId();
String getMetricType();
double getMetricValue();
AlertSeverity getSeverity();
String getMessage();
Date getAlertTimestamp();
}
52 changes: 52 additions & 0 deletions api/src/main/java/com/cloud/alert/ResourceAlertMetric.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package com.cloud.alert;

import java.util.Arrays;
import java.util.EnumSet;
import java.util.Set;

public enum ResourceAlertMetric {
CPU_UTILIZATION(ResourceAlertRule.ResourceType.VirtualMachine, ResourceAlertRule.ResourceType.Host),
MEMORY_UTILIZATION(ResourceAlertRule.ResourceType.VirtualMachine, ResourceAlertRule.ResourceType.Host),
DISK_READ_IOPS(ResourceAlertRule.ResourceType.VirtualMachine),
DISK_WRITE_IOPS(ResourceAlertRule.ResourceType.VirtualMachine),
DISK_READ_KBPS(ResourceAlertRule.ResourceType.VirtualMachine),
DISK_WRITE_KBPS(ResourceAlertRule.ResourceType.VirtualMachine),
STORAGE_UTILIZATION(ResourceAlertRule.ResourceType.StoragePool),
NETWORK_READ_KBPS(ResourceAlertRule.ResourceType.VirtualMachine, ResourceAlertRule.ResourceType.Host),
NETWORK_WRITE_KBPS(ResourceAlertRule.ResourceType.VirtualMachine, ResourceAlertRule.ResourceType.Host),
LOAD_AVERAGE(ResourceAlertRule.ResourceType.Host),
VOLUME_USED_GB(ResourceAlertRule.ResourceType.Volume),
VOLUME_UTILIZATION(ResourceAlertRule.ResourceType.Volume),
STORAGE_USED_IOPS(ResourceAlertRule.ResourceType.StoragePool);

private final Set<ResourceAlertRule.ResourceType> applicableTypes;

ResourceAlertMetric(ResourceAlertRule.ResourceType... types) {
this.applicableTypes = EnumSet.copyOf(Arrays.asList(types));
}

public boolean appliesTo(ResourceAlertRule.ResourceType type) {
return applicableTypes.contains(type);
}

public boolean isPercentage() {
return this == CPU_UTILIZATION || this == MEMORY_UTILIZATION || this == STORAGE_UTILIZATION || this == VOLUME_UTILIZATION;
}
}
48 changes: 48 additions & 0 deletions api/src/main/java/com/cloud/alert/ResourceAlertRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package com.cloud.alert;

import java.util.Date;

import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;

public interface ResourceAlertRule extends ControlledEntity, Identity, InternalIdentity {

enum ResourceType {
VirtualMachine, Volume, Host, StoragePool
}

enum State {
Enabled, Disabled
}

String getName();
ResourceType getResourceType();
Long getResourceId();
String getMetric();
AlertCondition getCondition();
double getThreshold();
AlertSeverity getSeverity();
String getMessage();
boolean isEmail();
int getResetInterval();
State getState();
Date getCreated();
}
5 changes: 5 additions & 0 deletions api/src/main/java/com/cloud/event/EventTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,11 @@ public class EventTypes {
public static final String EVENT_QUOTA_TARIFF_DELETE = "QUOTA.TARIFF.DELETE";
public static final String EVENT_QUOTA_TARIFF_UPDATE = "QUOTA.TARIFF.UPDATE";

// Resource alert rules
public static final String EVENT_RESOURCE_ALERT_RULE_CREATE = "RESOURCE.ALERT.RULE.CREATE";
public static final String EVENT_RESOURCE_ALERT_RULE_UPDATE = "RESOURCE.ALERT.RULE.UPDATE";
public static final String EVENT_RESOURCE_ALERT_RULE_DELETE = "RESOURCE.ALERT.RULE.DELETE";

// Routing
public static final String EVENT_ZONE_IP4_SUBNET_CREATE = "ZONE.IP4.SUBNET.CREATE";
public static final String EVENT_ZONE_IP4_SUBNET_UPDATE = "ZONE.IP4.SUBNET.UPDATE";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.apache.cloudstack.alert;

import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.command.user.resourcealert.CreateResourceAlertRuleCmd;
import org.apache.cloudstack.api.command.user.resourcealert.DeleteResourceAlertRuleCmd;
import org.apache.cloudstack.api.command.user.resourcealert.ListResourceAlertRulesCmd;
import org.apache.cloudstack.api.command.user.resourcealert.ListResourceAlertsCmd;
import org.apache.cloudstack.api.command.user.resourcealert.UpdateResourceAlertRuleCmd;
import org.apache.cloudstack.api.response.ResourceAlertResponse;
import org.apache.cloudstack.api.response.ResourceAlertRuleResponse;

import com.cloud.utils.component.PluggableService;

public interface ResourceAlertService extends PluggableService {

ResourceAlertRuleResponse createResourceAlertRule(CreateResourceAlertRuleCmd cmd);
ListResponse<ResourceAlertRuleResponse> listResourceAlertRules(ListResourceAlertRulesCmd cmd);
ResourceAlertRuleResponse updateResourceAlertRule(UpdateResourceAlertRuleCmd cmd);
boolean deleteResourceAlertRule(DeleteResourceAlertRuleCmd cmd);
ListResponse<ResourceAlertResponse> listResourceAlerts(ListResourceAlertsCmd cmd);
}
8 changes: 8 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,14 @@ public class ApiConstants {
public static final String AGGR_FUNCTION = "aggrfunction";
public static final String AGGR_VALUE = "aggrvalue";
public static final String THRESHOLD = "threshold";
public static final String METRIC = "metric";
public static final String CONDITION = "condition";
public static final String SEVERITY = "severity";
public static final String RESET_INTERVAL = "resetinterval";
public static final String WEBHOOK_IDS = "webhookids";
public static final String WEBHOOK_NAMES = "webhooknames";
public static final String CLEANUP_WEBHOOKS = "cleanupwebhooks";
public static final String ALERT_RULE_ID = "alertruleid";
public static final String RELATIONAL_OPERATOR = "relationaloperator";
public static final String OTHER_DEPLOY_PARAMS = "otherdeployparams";
public static final String MIN_MEMBERS = "minmembers";
Expand Down
Loading
Loading