1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package it.jnrpe.plugin;
17
18 import it.jnrpe.ICommandLine;
19 import it.jnrpe.Status;
20 import it.jnrpe.plugin.utils.SshUtils;
21 import it.jnrpe.plugin.utils.Utils;
22 import it.jnrpe.plugins.Metric;
23 import it.jnrpe.plugins.MetricGatheringException;
24 import it.jnrpe.plugins.PluginBase;
25 import it.jnrpe.plugins.annotations.Option;
26 import it.jnrpe.plugins.annotations.Plugin;
27 import it.jnrpe.plugins.annotations.PluginOptions;
28 import it.jnrpe.utils.BadThresholdException;
29 import it.jnrpe.utils.thresholds.ThresholdsEvaluatorBuilder;
30
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.math.BigDecimal;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.List;
37
38 import com.jcraft.jsch.Channel;
39 import com.jcraft.jsch.ChannelExec;
40 import com.jcraft.jsch.JSchException;
41 import com.jcraft.jsch.Session;
42
43
44
45
46
47
48
49
50 @Plugin(name = "CHECK_BY_SSH", description = "Use ssh to execute commands on a remote host.\n"
51 + "EXAMPLES:\n"
52 + "The example will be based upon the following command definition (ini file)\n\n"
53 + "check_by_ssh : CHECK_BY_SSH --hostname $ARG1$ --port $ARG2$ --password $ARG3$ -C $ARG4$\n"
54 + "check_nrpe -H myjnrpeserver -c check_ssh -a myhostname 22 password uptime")
55 @PluginOptions({
56 @Option(shortName = "h", longName = "hostname", description = "IP or hostname", required = true, hasArgs = true, argName = "hostname", optionalArgs = false, option = "hostname"),
57 @Option(shortName = "p", longName = "port", description = "Port number. Default is 22.", required = false, hasArgs = true, argName = "port", optionalArgs = false, option = "port"),
58 @Option(shortName = "u", longName = "username", description = "Username.", required = true, hasArgs = true, argName = "username", optionalArgs = false, option = "username"),
59 @Option(shortName = "P", longName = "password", description = "Password.", required = true, hasArgs = true, argName = "hostname", optionalArgs = false, option = "password"),
60 @Option(shortName = "t", longName = "timeout", description = "Seconds before connection times out (default: 10)", required = false, hasArgs = true, argName = "timeout", optionalArgs = false, option = "timeout"),
61 @Option(shortName = "w", longName = "warning", description = "Response time to result in warning status (seconds)", required = false, hasArgs = true, argName = "warning", optionalArgs = false, option = "warning"),
62 @Option(shortName = "c", longName = "critical", description = "Response time to result in critical status (seconds)", required = false, hasArgs = true, argName = "critical", optionalArgs = false, option = "critical"),
63 @Option(shortName = "C", longName = "command", description = "command to execute on the remote machine", required = true, hasArgs = true, argName = "command", optionalArgs = false, option = "command") })
64 public class CheckBySsh extends PluginBase {
65
66
67
68
69
70
71
72 private static final int ERR_CMD_NOT_FOUND = 127;
73
74
75
76
77 private static final int ERR_NO_PERMISSION = 126;
78
79 @Override
80 protected String getPluginName() {
81 return "CHECK_BY_SSH";
82 }
83
84 @Override
85 public final void configureThresholdEvaluatorBuilder(
86 final ThresholdsEvaluatorBuilder thrb, final ICommandLine cl)
87 throws BadThresholdException {
88 thrb.withLegacyThreshold("session", "1", null, "0");
89 thrb.withLegacyThreshold("response", null,
90 cl.getOptionValue("warning"), cl.getOptionValue("critical"));
91 thrb.withLegacyThreshold("result", "1", null, "0");
92
93 }
94
95 @Override
96 public final Collection<Metric> gatherMetrics(final ICommandLine cl)
97 throws MetricGatheringException {
98 List<Metric> metrics = new ArrayList<Metric>();
99 Session session = null;
100 Channel channel = null;
101 String command = cl.getOptionValue("command");
102 InputStream in = null;
103 boolean hasSession = false;
104 long then = System.currentTimeMillis();
105 try {
106 session = SshUtils.getSession(cl);
107 channel = session.openChannel("exec");
108
109 hasSession = true;
110 metrics.add(new Metric("session", "", new BigDecimal(1), null, null));
111 } catch (Exception e) {
112
113
114
115 log.debug(e.getMessage(), e);
116 throw new MetricGatheringException(
117 "SSH not started, permission denied.", Status.UNKNOWN, e);
118 }
119 try {
120 if (hasSession) {
121 ((ChannelExec) channel).setCommand(command);
122 channel.setInputStream(null);
123 ((ChannelExec) channel).setErrStream(System.err);
124 in = channel.getInputStream();
125 } else {
126 return metrics;
127 }
128 } catch (IOException e1) {
129
130 throw new MetricGatheringException(e1.getMessage(), Status.UNKNOWN,
131 e1);
132 }
133
134 try {
135 channel.connect();
136 metrics.add(new Metric("connected", "", new BigDecimal(1), null,
137 null));
138 } catch (JSchException e2) {
139
140 throw new MetricGatheringException(e2.getMessage(), Status.UNKNOWN,
141 e2);
142 }
143
144 StringBuffer sb = new StringBuffer();
145 byte[] tmp = new byte[1024];
146 int exitStatus = 0;
147 while (true) {
148 try {
149 while (in.available() > 0) {
150 int i = in.read(tmp, 0, 1024);
151 if (i < 0)
152 break;
153 sb.append(new String(tmp, 0, i, "UTF-8"));
154 }
155 } catch (IOException e1) {
156 throw new MetricGatheringException(e1.getMessage(),
157 Status.UNKNOWN, e1);
158 }
159 if (channel.isClosed()) {
160 exitStatus = channel.getExitStatus();
161 break;
162 }
163 try {
164 Thread.sleep(1000);
165 } catch (Exception e) {
166 e.printStackTrace();
167 }
168 }
169 if (channel != null) {
170 channel.disconnect();
171 }
172 if (session != null) {
173 session.disconnect();
174 }
175 long response = (System.currentTimeMillis() - then) / 1000;
176 metrics.add(new Metric("response", "", new BigDecimal(response), null,
177 null));
178
179 String msg = "";
180 switch (channel.getExitStatus()) {
181 case ERR_CMD_NOT_FOUND:
182 msg = "Command not found.";
183 break;
184 case ERR_NO_PERMISSION:
185 msg = "Not enough permission to execute command.";
186 break;
187 default:
188 break;
189 }
190
191 metrics.add(new Metric("result", msg + " " + sb.toString(),
192 new BigDecimal(Utils.getIntValue(exitStatus == 0)), null, null));
193 return metrics;
194 }
195 }