Hello mooli tayer,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/24707
to review the following change.
Change subject: tools: notifier: Support snmp trap as a notification method.
......................................................................
tools: notifier: Support snmp trap as a notification method.
See feature pages[1]
[1] http://www.ovirt.org/Features/engine-snmp
Change-Id: I0cd22d022ae535f45e046b09a2cbfadd837b465c
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1032661
Signed-off-by: Mooli Tayer <[email protected]>
Signed-off-by: Alon Bar-Lev <[email protected]>
---
M backend/manager/dependencies/pom.xml
A backend/manager/dependencies/src/main/modules/org/snmp4j/main/module.xml
M
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/EventNotificationMethod.java
M backend/manager/tools/pom.xml
M
backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/Notifier.java
A
backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/transport/snmp/Snmp.java
M
backend/manager/tools/src/main/modules/org/ovirt/engine/core/tools/main/module.xml
M ovirt-engine.spec.in
M packaging/dbscripts/upgrade/03_04_0600_event_notification_methods.sql
M packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
M pom.xml
11 files changed, 266 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/07/24707/1
diff --git a/backend/manager/dependencies/pom.xml
b/backend/manager/dependencies/pom.xml
index 8e75809..7d04543 100644
--- a/backend/manager/dependencies/pom.xml
+++ b/backend/manager/dependencies/pom.xml
@@ -225,6 +225,12 @@
<version>${aopalliance.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.snmp4j</groupId>
+ <artifactId>snmp4j</artifactId>
+ <version>${snmp4j.version}</version>
+ </dependency>
+
</dependencies>
<build>
@@ -441,6 +447,12 @@
<moduleName>org.aopalliance</moduleName>
</module>
+ <module>
+ <groupId>org.snmp4j</groupId>
+ <artifactId>snmp4j</artifactId>
+ <moduleName>org.snmp4j</moduleName>
+ </module>
+
</modules>
</configuration>
</plugin>
diff --git
a/backend/manager/dependencies/src/main/modules/org/snmp4j/main/module.xml
b/backend/manager/dependencies/src/main/modules/org/snmp4j/main/module.xml
new file mode 100644
index 0000000..e70d2d7
--- /dev/null
+++ b/backend/manager/dependencies/src/main/modules/org/snmp4j/main/module.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<module xmlns="urn:jboss:module:1.1" name="org.snmp4j">
+
+ <resources>
+ <resource-root path="snmp4j.jar"/>
+ </resources>
+
+ <dependencies>
+ <module name="org.slf4j"/>
+ </dependencies>
+
+</module>
diff --git
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/EventNotificationMethod.java
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/EventNotificationMethod.java
index 49a9321..70254cd 100644
---
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/EventNotificationMethod.java
+++
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/EventNotificationMethod.java
@@ -1,5 +1,6 @@
package org.ovirt.engine.core.common;
public enum EventNotificationMethod {
- EMAIL
+ EMAIL,
+ SNMP_TRAP
}
diff --git a/backend/manager/tools/pom.xml b/backend/manager/tools/pom.xml
index 0f8fe63..5f22940 100644
--- a/backend/manager/tools/pom.xml
+++ b/backend/manager/tools/pom.xml
@@ -21,6 +21,12 @@
<dependencies>
<dependency>
+ <groupId>org.snmp4j</groupId>
+ <artifactId>snmp4j</artifactId>
+ <version>${snmp4j.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>${engine.groupId}</groupId>
<artifactId>common</artifactId>
<version>${engine.version}</version>
diff --git
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/Notifier.java
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/Notifier.java
index 3b8e4f7..15be47c 100644
---
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/Notifier.java
+++
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/Notifier.java
@@ -10,6 +10,7 @@
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.ovirt.engine.core.notifier.transport.smtp.Smtp;
+import org.ovirt.engine.core.notifier.transport.snmp.Snmp;
import org.ovirt.engine.core.notifier.utils.NotificationProperties;
/**
@@ -57,6 +58,7 @@
notificationService = new NotificationService(prop);
engineMonitorService = new EngineMonitorService(prop);
notificationService.registerTransport(new Smtp(prop));
+ notificationService.registerTransport(new Snmp(prop));
if (!notificationService.hasTransports()) {
throw new RuntimeException("No transport is enabled, nothing
to do");
}
diff --git
a/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/transport/snmp/Snmp.java
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/transport/snmp/Snmp.java
new file mode 100644
index 0000000..990cb75
--- /dev/null
+++
b/backend/manager/tools/src/main/java/org/ovirt/engine/core/notifier/transport/snmp/Snmp.java
@@ -0,0 +1,183 @@
+package org.ovirt.engine.core.notifier.transport.snmp;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.ovirt.engine.core.common.AuditLogType;
+import org.ovirt.engine.core.common.EventNotificationMethod;
+import org.ovirt.engine.core.notifier.NotificationServiceException;
+import org.ovirt.engine.core.notifier.dao.DispatchResult;
+import org.ovirt.engine.core.notifier.filter.AuditLogEvent;
+import org.ovirt.engine.core.notifier.transport.Transport;
+import org.ovirt.engine.core.notifier.utils.NotificationProperties;
+import org.snmp4j.CommunityTarget;
+import org.snmp4j.PDU;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.UdpAddress;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.transport.DefaultUdpTransportMapping;
+
+public class Snmp extends Transport {
+
+ private static final Logger log = Logger.getLogger(Snmp.class);
+
+ private static final String SNMP_MANAGERS = "SNMP_MANAGERS";
+ private static final String SNMP_COMMUNITY = "SNMP_COMMUNITY";
+ private static final String SNMP_OID = "SNMP_OID";
+ private static final int ENTERPRISE_SPECIFIC = 6;
+ private static final Pattern PROFILE_PATTERN =
Pattern.compile(SNMP_MANAGERS + "(|_(?<profile>.*))");
+
+ private final Map<String, Profile> profiles = new HashMap<>();
+ private org.snmp4j.Snmp snmp = null;
+ private boolean active = false;
+
+ public Snmp(NotificationProperties props) {
+ for (Map.Entry<String, String> entry :
props.getProperties().entrySet()) {
+ Matcher m = PROFILE_PATTERN.matcher(entry.getKey());
+ if (m.matches()) {
+ String profile = m.group("profile") == null ? "" :
m.group("profile");
+ String managers = props.getProperty(SNMP_MANAGERS, profile,
false);
+ if (!StringUtils.isBlank(managers)) {
+ profiles.put(
+ profile,
+ new Profile(
+ managers,
+ props.getProperty(SNMP_COMMUNITY, profile, false),
+ props.getProperty(SNMP_OID, profile, false)
+ )
+ );
+ }
+ }
+ }
+
+ if (!profiles.isEmpty()) {
+ try {
+ // Create a new session and define it's transport.
+ snmp = new org.snmp4j.Snmp(new DefaultUdpTransportMapping());
+ } catch (IOException e) {
+ throw new NotificationServiceException("error creating " +
getClass().getName());
+ }
+ active = true;
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "snmp";
+ }
+
+ @Override
+ public boolean isActive() {
+ return active;
+ }
+
+ @Override
+ public void dispatchEvent(AuditLogEvent event, String address) {
+ Profile profile = profiles.get(address);
+ if (profile == null) {
+ profile = profiles.get("");
+ if (profile == null) {
+ log.warn("Could not find snmp profile: " + address);
+ return;
+ }
+ }
+
+ // PDU class is for SNMPv2c units
+ PDU v2pdu = new PDU();
+ v2pdu.setType(PDU.TRAP);
+ int auditLogTypeVal = AuditLogType.UNASSIGNED.getValue();
+ try {
+ // TODO mtayer: what about db? add to audit log type
+
+ auditLogTypeVal = AuditLogType.valueOf(event.getName()).getValue();
+ } catch (IllegalArgumentException e) {
+ log.warn("Could not find event: " + event.getName() + " in
auditLogTypes");
+ }
+ OID trapOID = SnmpConstants.getTrapOID(profile.oid,
ENTERPRISE_SPECIFIC, auditLogTypeVal);
+ v2pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, trapOID));
+ v2pdu.add(new VariableBinding(
+ new OID(trapOID).append(0),
+ new OctetString(event.getMessage())));
+ v2pdu.add(new VariableBinding(
+ new OID(trapOID).append(1),
+ new OctetString(event.getSeverity().name())));
+ v2pdu.add(new VariableBinding(
+ new OID(trapOID).append(2),
+ new OctetString(event.getType().name())));
+ v2pdu.add(new VariableBinding(
+ new OID(trapOID).append(3),
+ new OctetString(event.getLogTime().toString())));
+ CommunityTarget target = new CommunityTarget();
+ target.setCommunity(profile.community);
+ target.setVersion(SnmpConstants.version2c);
+ for (Host host : profile.hosts) {
+ try {
+ log.info(String.format("Generate an snmp trap for event: %s to
address: %s ",
+ event, host.name));
+ target.setAddress(
+ new UdpAddress(
+ InetAddress.getByName(host.name),
+ host.port
+ )
+ );
+ snmp.send(v2pdu, target);
+ notifyObservers(DispatchResult.success(event, address,
EventNotificationMethod.SNMP_TRAP));
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ notifyObservers(DispatchResult.failure(event, address,
EventNotificationMethod.SNMP_TRAP, e.getMessage()));
+ }
+ }
+ }
+
+ private static class Host {
+ public String name;
+ public int port = 162;
+
+ public Host(String name, String port) {
+ this.name = name;
+ if (port != null) {
+ try {
+ this.port = Integer.parseInt(port);
+ if (this.port <= 0 || this.port > 0xffff) {
+ throw new Exception("Bad port");
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Invalid port %s for snmp host %s",
+ port,
+ name
+ )
+ );
+ }
+ }
+ }
+ }
+
+ private static class Profile {
+ private static final Pattern HOST_PATTERN =
Pattern.compile("(?<host>[^:\\s]+)(:(?<port>[^\\s]*))?");
+
+ public List<Host> hosts = new LinkedList<>();
+ public OctetString community;
+ public OID oid;
+
+ public Profile(String managers, String community, String oid) {
+ Matcher m = HOST_PATTERN.matcher(managers);
+ while (m.find()) {
+ hosts.add(new Host(m.group("host"), m.group("port")));
+ }
+ this.community = new OctetString(community);
+ this.oid = new OID(oid);
+ }
+ }
+}
diff --git
a/backend/manager/tools/src/main/modules/org/ovirt/engine/core/tools/main/module.xml
b/backend/manager/tools/src/main/modules/org/ovirt/engine/core/tools/main/module.xml
index cf051a4..3f5fa07 100644
---
a/backend/manager/tools/src/main/modules/org/ovirt/engine/core/tools/main/module.xml
+++
b/backend/manager/tools/src/main/modules/org/ovirt/engine/core/tools/main/module.xml
@@ -18,6 +18,7 @@
<module name="org.ovirt.engine.core.compat"/>
<module name="org.ovirt.engine.core.utils"/>
<module name="org.postgresql"/>
+ <module name="org.snmp4j"/>
<module name="sun.jdk"/>
</dependencies>
diff --git a/ovirt-engine.spec.in b/ovirt-engine.spec.in
index 0dc2932..67847f9 100644
--- a/ovirt-engine.spec.in
+++ b/ovirt-engine.spec.in
@@ -199,6 +199,7 @@
Requires: openstack-java-resteasy-connector >= %{openstack_java_version}
Requires: postgresql-jdbc
Requires: quartz
+Requires: snmp4j
Requires: spring-ldap
Requires: springframework-aop
Requires: springframework-beans
@@ -648,6 +649,7 @@
org/apache/xmlrpc/main/xmlrpc-common.jar
org/postgresql/main/postgresql.jar postgresql-jdbc.jar
org/quartz/main/quartz.jar
+org/snmp4j/main/snmp4j.jar
org/springframework/main/spring-aop.jar springframework/spring-aop.jar
org/springframework/main/spring-asm.jar objectweb-asm/asm.jar
org/springframework/main/spring-beans.jar springframework/spring-beans.jar
diff --git
a/packaging/dbscripts/upgrade/03_04_0600_event_notification_methods.sql
b/packaging/dbscripts/upgrade/03_04_0600_event_notification_methods.sql
index 4187bc5..d515d92 100644
--- a/packaging/dbscripts/upgrade/03_04_0600_event_notification_methods.sql
+++ b/packaging/dbscripts/upgrade/03_04_0600_event_notification_methods.sql
@@ -4,7 +4,7 @@
-- save EventNotificationMethod as string with constraint.
ALTER TABLE event_subscriber ADD COLUMN notification_method CHARACTER
VARYING(32)
- CHECK (notification_method IN ('EMAIL'));
+ CHECK (notification_method IN ('EMAIL', 'SNMP_TRAP'));
ALTER TABLE event_subscriber DROP CONSTRAINT pk_event_subscriber;
ALTER TABLE event_subscriber
ADD CONSTRAINT pk_event_subscriber PRIMARY KEY (subscriber_id,
event_up_name, notification_method, tag_name);
diff --git
a/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
b/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
index 9f4ccb8..58fed0a 100644
--- a/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
+++ b/packaging/services/ovirt-engine-notifier/ovirt-engine-notifier.conf.in
@@ -131,6 +131,41 @@
# Amount of times to attempt sending an email before failing.
MAIL_RETRIES=4
+#-------------------------#
+# SNMP_TRAP Notifications #
+#-------------------------#
+# Send v2c snmp notifications
+
+# Minimum SNMP configuration
+#
+# Create @ENGINE_ETC@/notifier/notifier.conf.d/20-snmp.conf with:
+# SNMP_MANAGERS="host"
+# FILTERS="include:*(snmp:) ${FILTERS}"
+
+# Default whitespace separated IP/DNS list with optional port, default is 162.
+# SNMP_MANAGERS=manager1.example.com manager2.example.com:164
+SNMP_MANAGERS=
+
+# Default SNMP Community String.
+SNMP_COMMUNITY=public
+
+# Default TRAP Object Identifier for alerts.
+#
+#
iso.organization.DoD.Internet.private.enterprises.redhat.ovirt-engine.notifications.audit-log
+# 1.3.6.1.4.1.2312.13.1.1
+SNMP_OID=1.3.6.1.4.1.2312.13.1.1
+
+#
+# SNMP profile support
+#
+# Multiple SNMP profiles are supported.
+# Specify profile settings by using _profile suffix,
+# for example, to define a profile to sent specific
+# message to host3, specify:
+# SNMP_MANAGERS_profile1=host3
+# FILTER="include:VDC_START(snmp:profile1) ${FILTER}"
+#
+
#----------------------------------#
# Engine Monitoring Configuration: #
#----------------------------------#
diff --git a/pom.xml b/pom.xml
index 24e198e..5669ef3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,7 +92,7 @@
<tukaani-xz.version>1.0</tukaani-xz.version>
<c3p0.version>0.9.1.1</c3p0.version>
<aopalliance.version>1.0</aopalliance.version>
-
+ <snmp4j.version>2.2.2</snmp4j.version>
<!-- OpenStack -->
<openstack-client.version>3.0.2</openstack-client.version>
@@ -388,6 +388,14 @@
<enabled>false</enabled>
</snapshots>
</repository>
+ <repository>
+ <id>snmp4j</id>
+ <name>snmp4j</name>
+ <url>https://oosnmp.net/dist/release/</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
</repositories>
<pluginRepositories>
<pluginRepository>
--
To view, visit http://gerrit.ovirt.org/24707
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0cd22d022ae535f45e046b09a2cbfadd837b465c
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.4
Gerrit-Owner: Alon Bar-Lev <[email protected]>
Gerrit-Reviewer: mooli tayer <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches