All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.jnrpe.plugin.CheckBySsh Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2007, 2014 Massimiliano Ziccardi
 *
 * Licensed 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 it.jnrpe.plugin;

import it.jnrpe.ICommandLine;
import it.jnrpe.Status;
import it.jnrpe.plugin.utils.SshUtils;
import it.jnrpe.plugin.utils.Utils;
import it.jnrpe.plugins.Metric;
import it.jnrpe.plugins.MetricGatheringException;
import it.jnrpe.plugins.PluginBase;
import it.jnrpe.plugins.annotations.Option;
import it.jnrpe.plugins.annotations.Plugin;
import it.jnrpe.plugins.annotations.PluginOptions;
import it.jnrpe.utils.BadThresholdException;
import it.jnrpe.utils.thresholds.ThresholdsEvaluatorBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

/**
 * This plugins executes remote commands through ssh and returns the command's
 * output (if successul).
 * 
 * @author Frederico Campos
 * 
 */
@Plugin(name = "CHECK_BY_SSH", description = "Use ssh to execute commands on a remote host.\n" + "EXAMPLES:\n"
        + "The example will be based upon the following command definition (ini file)\n\n"
        + "check_by_ssh : CHECK_BY_SSH --hostname $ARG1$ --port $ARG2$ --password $ARG3$ -C $ARG4$\n"
        + "check_nrpe -H myjnrpeserver -c check_ssh -a myhostname 22 password uptime")
@PluginOptions({
        @Option(shortName = "h", longName = "hostname", description = "IP or hostname", required = true, hasArgs = true, argName = "hostname", optionalArgs = false, option = "hostname"),
        @Option(shortName = "p", longName = "port", description = "Port number. Default is 22.", required = false, hasArgs = true, argName = "port", optionalArgs = false, option = "port"),
        @Option(shortName = "u", longName = "username", description = "Username.", required = true, hasArgs = true, argName = "username", optionalArgs = false, option = "username"),
        @Option(shortName = "P", longName = "password", description = "Password.", required = true, hasArgs = true, argName = "hostname", optionalArgs = false, option = "password"),
        @Option(shortName = "t", longName = "timeout", description = "Seconds before connection times out (default: 10)", required = false, hasArgs = true, argName = "timeout", optionalArgs = false, option = "timeout"),
        @Option(shortName = "w", longName = "warning", description = "Response time to result in warning status (seconds)", required = false, hasArgs = true, argName = "warning", optionalArgs = false, option = "warning"),
        @Option(shortName = "c", longName = "critical", description = "Response time to result in critical status (seconds)", required = false, hasArgs = true, argName = "critical", optionalArgs = false, option = "critical"),
        @Option(shortName = "C", longName = "command", description = "command to execute on the remote machine", required = true, hasArgs = true, argName = "command", optionalArgs = false, option = "command") })
public class CheckBySsh extends PluginBase {

    /**
     * Possible unix return codes
     */
    /**
     * command not found
     */
    private static final int ERR_CMD_NOT_FOUND = 127;

    /**
     * no permision
     */
    private static final int ERR_NO_PERMISSION = 126;

    @Override
    protected String getPluginName() {
        return "CHECK_BY_SSH";
    }

    @Override
    public final void configureThresholdEvaluatorBuilder(final ThresholdsEvaluatorBuilder thrb, final ICommandLine cl) throws BadThresholdException {
        thrb.withLegacyThreshold("session", "1", null, "0");
        thrb.withLegacyThreshold("response", null, cl.getOptionValue("warning"), cl.getOptionValue("critical"));
        thrb.withLegacyThreshold("result", "1", null, "0");

    }

    @Override
    public final Collection gatherMetrics(final ICommandLine cl) throws MetricGatheringException {
        List metrics = new ArrayList();
        Session session = null;
        Channel channel = null;
        String command = cl.getOptionValue("command");
        InputStream in = null;
        boolean hasSession = false;
        long then = System.currentTimeMillis();
        try {
            session = SshUtils.getSession(cl);
            channel = session.openChannel("exec");

            hasSession = true;
            metrics.add(new Metric("session", "", new BigDecimal(1), null, null));
        } catch (Exception e) {
            // metrics.add(new Metric("session",
            // "SSH not started, permission denied. " + e.getMessage(),
            // new BigDecimal(0), null, null));
            LOG.debug(getContext(), e.getMessage(), e);
            throw new MetricGatheringException("SSH not started, permission denied.", Status.UNKNOWN, e);
        }
        try {
            if (hasSession) {
                ((ChannelExec) channel).setCommand(command);
                channel.setInputStream(null);
                ((ChannelExec) channel).setErrStream(System.err);
                in = channel.getInputStream();
            } else {
                return metrics;
            }
        } catch (IOException e1) {
            // e1.printStackTrace();
            throw new MetricGatheringException(e1.getMessage(), Status.UNKNOWN, e1);
        }

        try {
            channel.connect();
            metrics.add(new Metric("connected", "", new BigDecimal(1), null, null));
        } catch (JSchException e2) {
            // e2.printStackTrace();
            throw new MetricGatheringException(e2.getMessage(), Status.UNKNOWN, e2);
        }

        StringBuilder sb = new StringBuilder();
        byte[] tmp = new byte[1024];
        int exitStatus = 0;
        while (true) {
            try {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0)
                        break;
                    sb.append(new String(tmp, 0, i, "UTF-8"));
                }
            } catch (IOException e1) {
                throw new MetricGatheringException(e1.getMessage(), Status.UNKNOWN, e1);
            }
            if (channel.isClosed()) {
                exitStatus = channel.getExitStatus();
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                LOG.error(getContext(), "gatherMetrics - " + e.getMessage(), e);
            }
        }
        if (channel != null) {
            channel.disconnect();
        }

        session.disconnect();
        long response = (System.currentTimeMillis() - then) / 1000;
        metrics.add(new Metric("response", "", new BigDecimal(response), null, null));
        // sb.append("\nexit-status: " + channel.getExitStatus());
        String msg = "";
        switch (channel.getExitStatus()) {
        case ERR_CMD_NOT_FOUND:
            msg = "Command not found.";
            break;
        case ERR_NO_PERMISSION:
            msg = "Not enough permission to execute command.";
            break;
        default:
            break;
        }

        metrics.add(new Metric("result", msg + " " + sb.toString(), new BigDecimal(Utils.getIntValue(exitStatus == 0)), null, null));
        return metrics;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy