/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-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.core.utils.InetAddressUtils; import org.opennms.core.utils.ParameterMap; 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.SnmpInstId; import org.opennms.netmgt.snmp.SnmpObjId; import org.opennms.netmgt.snmp.SnmpUtils; import org.opennms.netmgt.snmp.SnmpValue; /** * <P> * This class is designed to be used by the service poller framework to test the * status of PERC raid controllers on Dell Servers. The class implements * the ServiceMonitor interface that allows it to be used along with other * plug-ins by the service poller framework. * </P> * <p> * This does SNMP and therefore relies on the SNMP configuration so it is not distributable. * </p> * * @author <A HREF="mailto:tarus@opennms.org">Tarus Balog </A> * @author <A HREF="http://www.opennms.org/">OpenNMS </A> */ @Distributable(DistributionContext.DAEMON) final public class PercMonitor extends SnmpMonitorStrategy { /** * Name of monitored service. */ private static final String SERVICE_NAME = "PERC"; /** * The base OID for the logical device status information */ private static final String LOGICAL_BASE_OID = ".1.3.6.1.4.1.3582.1.1.2.1.3"; /** * The base OID for the physical device status information */ private static final String PHYSICAL_BASE_OID = ".1.3.6.1.4.1.3582.1.1.3.1.4"; private static final String ARRAY_POSITION_BASE_OID = ".1.3.6.1.4.1.3582.1.1.3.1.5"; /** * <P> * Returns the name of the service that the plug-in monitors ("SNMP"). * </P> * * @return The service that the plug-in monitors. */ public String serviceName() { return SERVICE_NAME; } /** * {@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(); PollStatus status = PollStatus.unavailable(); InetAddress ipaddr = (InetAddress) iface.getAddress(); // Retrieve this interface's SNMP peer object // // 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); // Get configuration parameters // // 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())); String arrayNumber = ParameterMap.getKeyedString(parameters,"array","0.0"); if (log().isDebugEnabled()) log().debug("poll: service= SNMP address= " + agentConfig); // Establish SNMP session with interface // try { if (log().isDebugEnabled()) { log().debug("PercMonitor.poll: SnmpAgentConfig address: " +agentConfig); } SnmpObjId snmpObjectId = SnmpObjId.get(LOGICAL_BASE_OID + "." + arrayNumber); // First walk the physical OID Tree and check the returned values String returnValue = ""; SnmpValue value = SnmpUtils.get(agentConfig,snmpObjectId); if (value.toInt()!=2){ log().debug("PercMonitor.poll: Bad Disk Found"); returnValue = "log vol(" + arrayNumber + ") degraded"; // XXX should degraded be the virtualDiskState ? // array is bad // lets find out which disks are bad in the array // first we need to fetch the arrayPosition table. SnmpObjId arrayPositionSnmpObject = SnmpObjId.get(ARRAY_POSITION_BASE_OID); SnmpObjId diskStatesSnmpObject = SnmpObjId.get(PHYSICAL_BASE_OID); Map<SnmpInstId,SnmpValue> arrayDisks = SnmpUtils.getOidValues(agentConfig, "PercMonitor", arrayPositionSnmpObject); Map<SnmpInstId,SnmpValue> diskStates = SnmpUtils.getOidValues(agentConfig, "PercMonitor", diskStatesSnmpObject); for (Map.Entry<SnmpInstId, SnmpValue> disk: arrayDisks.entrySet()) { if (disk.getValue().toString().contains("A" + arrayNumber.toString() + "-")) { // this is a member of the array if ( diskStates.get(disk.getKey()).toInt() !=3 ){ // this is bad disk. returnValue += "phy drv(" + disk.getKey().toString() + ")"; } } return PollStatus.unavailable(returnValue); } } status = PollStatus.available(); } catch (NumberFormatException e) { status = logDown(Level.ERROR, "Number operator used on a non-number " + e.getMessage()); } catch (IllegalArgumentException e) { status = logDown(Level.ERROR, "Invalid SNMP Criteria: " + e.getMessage()); } catch (Throwable t) { status = logDown(Level.WARN, "Unexpected exception during SNMP poll of interface " + hostAddress, t); } return status; } }