/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2009-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.poller.monitors; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.net.InetAddress; import java.util.Map; import org.apache.log4j.Level; import org.opennms.netmgt.config.SnmpPeerFactory; import org.opennms.netmgt.model.PollStatus; import org.opennms.netmgt.poller.Distributable; import org.opennms.netmgt.poller.DistributionContext; import org.opennms.netmgt.poller.MonitoredService; import org.opennms.netmgt.poller.NetworkInterface; import org.opennms.netmgt.snmp.SnmpAgentConfig; import org.opennms.netmgt.snmp.SnmpObjId; import org.opennms.netmgt.snmp.SnmpUtils; import org.opennms.netmgt.snmp.SnmpValue; import org.opennms.core.utils.InetAddressUtils; import org.opennms.core.utils.ParameterMap; /** * <p> * This class is used to monitor Dell OpenManage chassis. The specific OIDs * referenced to "SNMP Reference Guide", available from * http://support.dell.com/support/edocs/software/svradmin/6.1/en * </p> * <p> * This does SNMP and therefore relies on the SNMP configuration so it is not distributable. * </p> * * @author <A HREF="mailto:r.trommer@open-factory.org">Ronny Trommer</A> */ @Distributable(DistributionContext.DAEMON) final public class OpenManageChassisMonitor extends SnmpMonitorStrategy { /** * Name of monitored service. */ private static final String m_serviceName = "Dell_OpenManageChassis"; /** * Defines the status of the chassis. */ private static final String CHASSIS_STATUS_OID = ".1.3.6.1.4.1.674.10892.1.300.10.1.4.1"; /** * Defines the overall status of this chassis (ESM) event log. */ private static final String EVENT_LOG_STATUS_OID = ".1.3.6.1.4.1.674.10892.1.200.10.1.41.1"; /** * Defines the manufacturer's name for this chassis. */ private static final String MANUFACTURER_OID = ".1.3.6.1.4.1.674.10892.1.300.10.1.8.1"; /** * Defines the status of the chassis. */ private static final String MODEL_NAME_OID = "1.3.6.1.4.1.674.10892.1.300.10.1.9.1"; /** * Defines the service tag name for this chassis. */ private static final String SERVICE_TAG_OID = ".1.3.6.1.4.1.674.10892.1.300.10.1.11.1"; /** * Implement the dell status */ private enum DELL_STATUS { OTHER(1), UNKNOWN(2), OK(3), NON_CRITICAL(4), CRITICAL(5), NON_RECOVERABLE(6); private final int state; // state code DELL_STATUS(int s) { this.state = s; } private int value() { return this.state; } }; /** * <P> * Returns the name of the service that the plug-in monitors * </P> * * @return The service that the plug-in monitors. */ public String serviceName() { return m_serviceName; } /** * {@inheritDoc} * * <P> * Initialize the service monitor. * </P> * @exception RuntimeException * Thrown if an unrecoverable error occurs that prevents * the plug-in from functioning. */ public void initialize(Map<String,Object> parameters) { // Initialize the SnmpPeerFactory // try { SnmpPeerFactory.init(); } catch (IOException ex) { log().fatal("initialize: Failed to load SNMP configuration", ex); throw new UndeclaredThrowableException(ex); } return; } /** * <P> * Called by the poller framework when an interface is being added to the * scheduler. Here we perform any necessary initialization to prepare the * NetworkInterface object for polling. * </P> * * @exception RuntimeException * Thrown if an unrecoverable error occurs that prevents * the interface from being monitored. * @param svc a {@link org.opennms.netmgt.poller.MonitoredService} object. */ public void initialize(MonitoredService svc) { super.initialize(svc); return; } /** * {@inheritDoc} * * <P> * The poll() method is responsible for polling the specified address for * SNMP service availability. * </P> * @exception RuntimeException * Thrown for any uncrecoverable errors. */ public PollStatus poll(MonitoredService svc, Map<String,Object> parameters) { NetworkInterface<InetAddress> iface = svc.getNetInterface(); String returnValue = ""; PollStatus status = PollStatus.unavailable(); InetAddress ipaddr = (InetAddress) iface.getAddress(); // Initialize the messages if the session is down String eventLogStatusTxt = "N/A"; String manufacturerName = "N/A"; String modelName = "N/A"; String serviceTagTxt = "N/A"; String chassisStatusTxt = "N/A"; // Retrieve this interface's SNMP peer object // SnmpAgentConfig agentConfig = SnmpPeerFactory.getInstance().getAgentConfig(ipaddr); if (agentConfig == null) throw new RuntimeException("SnmpAgentConfig object not available for interface " + ipaddr); final String hostAddress = InetAddressUtils.str(ipaddr); log().debug("poll: setting SNMP peer attribute for interface " + hostAddress); // set timeout and retries on SNMP peer object // agentConfig.setTimeout(ParameterMap.getKeyedInteger(parameters, "timeout", agentConfig.getTimeout())); agentConfig.setRetries(ParameterMap.getKeyedInteger(parameters, "retry", ParameterMap.getKeyedInteger(parameters, "retries", agentConfig.getRetries()))); agentConfig.setPort(ParameterMap.getKeyedInteger(parameters, "port", agentConfig.getPort())); // Establish SNMP session with interface // try { if (log().isDebugEnabled()) { log().debug("poll: SnmpAgentConfig address: " + agentConfig); } // Get the chassis status SnmpObjId chassisStatusSnmpObject = SnmpObjId.get(CHASSIS_STATUS_OID); SnmpValue chassisStatus = SnmpUtils.get(agentConfig, chassisStatusSnmpObject); // If no chassis status is received or SNMP is not possible, // service is down if (chassisStatus == null) { log().warn("No chassis status received!"); return status; } else { if (log().isDebugEnabled()) { log().debug("poll: chassis status: " + chassisStatus); } } /* * Do no unnecessary SNMP requests, if chassis status is OK, * return with service available and go away. */ if (chassisStatus.toInt() == DELL_STATUS.OK.value()) { if (log().isDebugEnabled()) { log().debug("poll: chassis status: " + chassisStatus.toInt()); } return PollStatus.available(); } else { if (log().isDebugEnabled()) { log().debug("poll: chassis status: " + chassisStatus.toInt()); } chassisStatusTxt = resolveDellStatus(chassisStatus.toInt()); } // Chassis status is not OK gather some information SnmpObjId eventLogStatusSnmpObject = SnmpObjId.get(EVENT_LOG_STATUS_OID); SnmpValue eventLogStatus = SnmpUtils.get(agentConfig, eventLogStatusSnmpObject); // Check correct MIB-Support if (eventLogStatus == null) { log().warn("Cannot receive eventLogStatus."); } else { if (log().isDebugEnabled()) { log().debug("poll: eventLogStatus: " + eventLogStatus); } eventLogStatusTxt = resolveDellStatus(eventLogStatus.toInt()); } SnmpObjId manufacturerSnmpObject = SnmpObjId.get(MANUFACTURER_OID); SnmpValue manufacturer = SnmpUtils.get(agentConfig, manufacturerSnmpObject); // Check correct MIB-Support if (manufacturer == null) { log().warn("Cannot receive manufacturer."); } else { if (log().isDebugEnabled()) { log().debug("poll: manufacturer: " + manufacturer); } manufacturerName = manufacturer.toString(); } SnmpObjId modelSnmpObject = SnmpObjId.get(MODEL_NAME_OID); SnmpValue model = SnmpUtils.get(agentConfig, modelSnmpObject); // Check correct MIB-Support if (model == null) { log().warn("Cannot receive model name."); } else { if (log().isDebugEnabled()) { log().debug("poll: model name: " + model); } modelName = model.toString(); } SnmpObjId serviceTagSnmpObject = SnmpObjId.get(SERVICE_TAG_OID); SnmpValue serviceTag = SnmpUtils.get(agentConfig, serviceTagSnmpObject); // Check correct MIB-Support if (serviceTag == null) { log().warn("Cannot receive service tag"); } else { if (log().isDebugEnabled()) { log().debug("poll: service tag: " + serviceTag); } serviceTagTxt = serviceTag.toString(); } returnValue = "Chassis status from " + manufacturerName + " " + modelName + " with service tag " + serviceTagTxt + " is " + chassisStatusTxt + ". Last event log status is " + eventLogStatusTxt + ". For further information, check your OpenManage website!"; // Set service down and return gathered information status = PollStatus.unavailable(returnValue); } catch (NullPointerException e) { status = logDown(Level.WARN, "Unexpected error during SNMP poll of interface " + hostAddress, e); } catch (NumberFormatException e) { status = logDown(Level.WARN, "Number operator used on a non-number " + e.getMessage()); } catch (IllegalArgumentException e) { status = logDown(Level.WARN, "Invalid SNMP Criteria: " + e.getMessage()); } catch (Throwable t) { status = logDown(Level.WARN, "Unexpected exception during SNMP poll of interface " + hostAddress, t); } // If matchAll is set to true, then the status is set to available // above with a single match. // Otherwise, the service will be unavailable. return status; } /** * Method to resolve a given Dell status to human readable string. * * @param sc * Dell status code * @return Human readable Dell status */ private String resolveDellStatus(int sc) { String name = "N/A"; if (DELL_STATUS.OTHER.value() == sc) name = DELL_STATUS.OTHER.name(); if (DELL_STATUS.UNKNOWN.value() == sc) name = DELL_STATUS.UNKNOWN.name(); if (DELL_STATUS.OK.value() == sc) name = DELL_STATUS.OK.name(); if (DELL_STATUS.NON_CRITICAL.value() == sc) name = DELL_STATUS.NON_CRITICAL.name(); if (DELL_STATUS.CRITICAL.value() == sc) name = DELL_STATUS.CRITICAL.name(); if (DELL_STATUS.NON_RECOVERABLE.value() == sc) name = DELL_STATUS.NON_RECOVERABLE.name(); return name; } }