source: nscp/modules/CheckHelpers/CheckHelpers.cpp @ e11d494

0.4.00.4.10.4.2
Last change on this file since e11d494 was e11d494, checked in by Michael Medin <michael@…>, 22 months ago

2011-07-25

  • merged in all 0.3.9 changes into 0.4.0
  • refactored where filter to be "non template" to drastically reduce compile time (as well as potentially size if I ever go dll instead of static link)
  • streamlined checkeventlog toi be same as "the other" where filters as well as dropped support of "old" syntax.
  • Property mode set to 100644
File size: 12.7 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21#include "stdafx.h"
22#include "CheckHelpers.h"
23#include <strEx.h>
24#include <time.h>
25#include <utils.h>
26#include <vector>
27#include <program_options_ex.hpp>
28#include <boost/program_options.hpp>
29#include <boost/thread/thread.hpp>
30
31#include <settings/client/settings_client.hpp>
32
33
34CheckHelpers gCheckHelpers;
35
36CheckHelpers::CheckHelpers() {
37}
38CheckHelpers::~CheckHelpers() {
39}
40
41
42bool CheckHelpers::loadModule() {
43        return false;
44}
45
46bool CheckHelpers::loadModuleEx(std::wstring alias, NSCAPI::moduleLoadMode mode) {
47        try {
48                get_core()->registerCommand(_T("CheckAlwaysOK"), _T("Run another check and regardless of its return code return OK."));
49                get_core()->registerCommand(_T("CheckAlwaysCRITICAL"), _T("Run another check and regardless of its return code return CRIT."));
50                get_core()->registerCommand(_T("CheckAlwaysWARNING"), _T("Run another check and regardless of its return code return WARN."));
51                get_core()->registerCommand(_T("CheckMultiple"), _T("Run more then one check and return the worst state."));
52                get_core()->registerCommand(_T("CheckOK"), _T("Just return OK (anything passed along will be used as a message)."));
53                get_core()->registerCommand(_T("check_ok"), _T("Just return OK (anything passed along will be used as a message)."));
54                get_core()->registerCommand(_T("CheckWARNING"), _T("Just return WARN (anything passed along will be used as a message)."));
55                get_core()->registerCommand(_T("CheckCRITICAL"), _T("Just return CRIT (anything passed along will be used as a message)."));
56                get_core()->registerCommand(_T("CheckVersion"), _T("Just return the nagios version (along with OK status)."));
57        } catch (nscapi::nscapi_exception &e) {
58                NSC_LOG_ERROR_STD(_T("Failed to register command: ") + e.msg_);
59        } catch (...) {
60                NSC_LOG_ERROR_STD(_T("Failed to register command."));
61        }
62        return true;
63}
64bool CheckHelpers::unloadModule() {
65        return true;
66}
67
68bool CheckHelpers::hasCommandHandler() {
69        return true;
70}
71bool CheckHelpers::hasMessageHandler() {
72        return false;
73}
74NSCAPI::nagiosReturn CheckHelpers::checkSimpleStatus(NSCAPI::nagiosReturn status, const std::list<std::wstring> arguments, std::wstring &message, std::wstring &perf)
75{
76        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
77        if (arguments.empty()) {
78                message = nscapi::plugin_helper::translateReturn(status) + _T(": Lets pretend everything is going to be ok.");
79                return status;
80        }
81        std::list<std::wstring>::const_iterator cit;
82        for (cit=arguments.begin();cit!=arguments.end();++cit)
83                message += *cit;
84        return status;
85}
86
87NSCAPI::nagiosReturn CheckHelpers::handleCommand(const std::wstring command, std::list<std::wstring> arguments, std::wstring &message, std::wstring &perf) {
88        if (command == _T("checkversion")) {
89                message = GET_CORE()->getApplicationVersionString();
90                return NSCAPI::returnOK;
91        } else if (command == _T("checkalwaysok")) {
92                if (arguments.size() < 1) {
93                        message = _T("ERROR: Missing arguments.");
94                        return NSCAPI::returnUNKNOWN;
95                }
96                std::wstring new_command = arguments.front(); arguments.pop_front();
97                GET_CORE()->InjectSimpleCommand(new_command, arguments, message, perf);
98                return NSCAPI::returnOK;
99        } else if (command == _T("checkalwayscritical")) {
100                if (arguments.size() < 1) {
101                        message = _T("ERROR: Missing arguments.");
102                        return NSCAPI::returnUNKNOWN;
103                }
104                std::wstring new_command = arguments.front(); arguments.pop_front();
105                GET_CORE()->InjectSimpleCommand(new_command, arguments, message, perf);
106                return NSCAPI::returnCRIT;
107        } else if (command == _T("checkalwayswarning")) {
108                if (arguments.size() < 1) {
109                        message = _T("ERROR: Missing arguments.");
110                        return NSCAPI::returnUNKNOWN;
111                }
112                std::wstring new_command = arguments.front(); arguments.pop_front();
113                GET_CORE()->InjectSimpleCommand(new_command, arguments, message, perf);
114                return NSCAPI::returnWARN;
115        } else if (command == _T("checkok")) {
116                return checkSimpleStatus(NSCAPI::returnOK, arguments, message, perf);
117        } else if (command == _T("check_ok")) {
118                return checkSimpleStatus(NSCAPI::returnOK, arguments, message, perf);
119        } else if (command == _T("checkwarning")) {
120                return checkSimpleStatus(NSCAPI::returnWARN, arguments, message, perf);
121        } else if (command == _T("checkcritical")) {
122                return checkSimpleStatus(NSCAPI::returnCRIT, arguments, message, perf);
123        } else if (command == _T("checkmultiple")) {
124                return checkMultiple(arguments, message, perf);
125        } else if (command == _T("Negate")) {
126                return negate(arguments, message, perf);
127        } else if (command == _T("Timeout")) {
128                return timeout(arguments, message, perf);
129        }
130        return NSCAPI::returnIgnored;
131}
132NSCAPI::nagiosReturn CheckHelpers::checkMultiple(const std::list<std::wstring> arguments, std::wstring &message, std::wstring &perf)
133{
134        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
135        if (arguments.empty()) {
136                message = _T("Missing argument(s).");
137                return NSCAPI::returnCRIT;
138        }
139        typedef std::pair<std::wstring, std::list<std::wstring> > sub_command;
140        std::list<sub_command> commands;
141        sub_command currentCommand;
142        std::list<std::wstring>::const_iterator cit;
143        for (cit=arguments.begin();cit!=arguments.end();++cit) {
144                std::wstring arg = *cit;
145                std::pair<std::wstring,std::wstring> p = strEx::split(arg,_T("="));
146                if (p.first == _T("command")) {
147                        if (!currentCommand.first.empty())
148                                commands.push_back(currentCommand);
149                        currentCommand.first = p.second;
150                        currentCommand.second.clear();
151                } else {
152                        currentCommand.second.push_back(*cit);
153                }
154        }
155        if (!currentCommand.first.empty())
156                commands.push_back(currentCommand);
157        std::list<sub_command>::iterator cit2;
158        for (cit2 = commands.begin(); cit2 != commands.end(); ++cit2) {
159                std::list<std::wstring> sub_args;
160                std::wstring tMsg, tPerf;
161                NSCAPI::nagiosReturn tRet = GET_CORE()->InjectSimpleCommand((*cit2).first.c_str(), (*cit2).second, tMsg, tPerf);
162                returnCode = nscapi::plugin_helper::maxState(returnCode, tRet);
163                if (!message.empty())
164                        message += _T(", ");
165                message += tMsg;
166                perf += tPerf;
167        }
168        return returnCode;
169}
170
171NSCAPI::nagiosReturn CheckHelpers::negate(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
172{
173        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
174        if (arguments.empty()) {
175                msg = _T("Missing argument(s).");
176                return NSCAPI::returnCRIT;
177        }
178
179        std::wstring command;
180        NSCAPI::nagiosReturn OK = NSCAPI::returnOK, WARN = NSCAPI::returnWARN, CRIT = NSCAPI::returnCRIT, UNKNOWN = NSCAPI::returnUNKNOWN;
181        std::vector<std::wstring> cmd_args;
182
183        //#define USE_BOOST
184
185        try {
186
187
188                boost::program_options::options_description desc("Allowed options");
189                desc.add_options()
190                        ("help,h", "Show this help message.")
191
192                        ("ok,o",                boost::program_options::wvalue<std::wstring>(), "The state to return instead of OK")
193                        ("warning,w",   boost::program_options::wvalue<std::wstring>(), "The state to return instead of WARNING")
194                        ("critical,c",  boost::program_options::wvalue<std::wstring>(), "The state to return instead of CRITICAL")
195                        ("unknown,u",   boost::program_options::wvalue<std::wstring>(), "The state to return instead of UNKNOWN")
196
197                        ("command,q",   boost::program_options::wvalue<std::wstring>(&command), "Wrapped command to execute")
198                        ("arguments,a", boost::program_options::wvalue<std::vector<std::wstring> >(&cmd_args), "List of arguments (for wrapped command)")
199                        ;
200
201                boost::program_options::positional_options_description p;
202                p.add("arguments", -1);
203
204                std::vector<std::wstring> arg_list(arguments.begin(), arguments.end());
205
206                boost::program_options::variables_map vm;
207                boost::program_options::store(boost::program_options::basic_command_line_parser<wchar_t>(arg_list).options(desc).positional(p).run(), vm);
208                boost::program_options::notify(vm);
209
210                if (vm.count("help")) {
211                        std::stringstream ss;
212                        desc.print(ss);
213                        msg = strEx::string_to_wstring(ss.str());
214                        return NSCAPI::returnUNKNOWN;
215                }
216
217                if (vm.count("ok"))
218                        OK = nscapi::plugin_helper::translateReturn(vm["ok"].as<std::wstring>());
219                if (vm.count("warning"))
220                        WARN = nscapi::plugin_helper::translateReturn(vm["warning"].as<std::wstring>());
221                if (vm.count("critical"))
222                        CRIT = nscapi::plugin_helper::translateReturn(vm["critical"].as<std::wstring>());
223                if (vm.count("unknown"))
224                        UNKNOWN = nscapi::plugin_helper::translateReturn(vm["unknown"].as<std::wstring>());
225
226        } catch (std::exception &e) {
227                msg = _T("Could not parse command: ") + strEx::string_to_wstring(e.what());
228                return NSCAPI::returnCRIT;
229        } catch (...) {
230                msg = _T("Could not parse command: <UNKNOWN EXCEPTION>");
231                return NSCAPI::returnCRIT;
232        }
233        std::list<std::wstring> cmd_args_l(cmd_args.begin(), cmd_args.end());
234
235        NSCAPI::nagiosReturn tRet = GET_CORE()->InjectSimpleCommand(command, cmd_args_l, msg, perf);
236        switch (tRet) {
237                case NSCAPI::returnOK:
238                        return OK;
239                case NSCAPI::returnCRIT:
240                        return CRIT;
241                case NSCAPI::returnWARN:
242                        return WARN;
243                case NSCAPI::returnUNKNOWN:
244                        return UNKNOWN;
245                default:
246                        return UNKNOWN;
247        }
248}
249
250
251class worker {
252public:
253        void proc(std::wstring command, std::list<std::wstring> arguments) {
254                code = GET_CORE()->InjectSimpleCommand(command, arguments, msg, perf);
255        }
256        std::wstring msg;
257        std::wstring perf;
258        NSCAPI::nagiosReturn code;
259
260};
261
262NSCAPI::nagiosReturn CheckHelpers::timeout(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
263{
264        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
265        if (arguments.empty()) {
266                msg = _T("Missing argument(s).");
267                return NSCAPI::returnCRIT;
268        }
269
270        std::wstring command;
271        NSCAPI::nagiosReturn retCode = NSCAPI::returnUNKNOWN;
272        std::vector<std::wstring> cmd_args;
273        unsigned long timeout = 30;
274
275        try {
276
277                boost::program_options::options_description desc("Allowed options");
278                desc.add_options()
279                        ("help,h", "Show this help message.")
280
281                        ("timeout,t",   boost::program_options::value<unsigned long>(&timeout), "The timeout value")
282
283                        ("command,q",   boost::program_options::wvalue<std::wstring>(&command), "Wrapped command to execute")
284                        ("arguments,a", boost::program_options::wvalue<std::vector<std::wstring> >(&cmd_args), "List of arguments (for wrapped command)")
285                        ;
286
287                boost::program_options::positional_options_description p;
288                p.add("arguments", -1);
289
290                std::vector<std::wstring> arg_list(arguments.begin(), arguments.end());
291
292                boost::program_options::variables_map vm;
293                boost::program_options::store(boost::program_options::basic_command_line_parser<wchar_t>(arg_list).options(desc).positional(p).run(), vm);
294                boost::program_options::notify(vm);
295
296                if (vm.count("help")) {
297                        std::stringstream ss;
298                        desc.print(ss);
299                        msg = strEx::string_to_wstring(ss.str());
300                        return NSCAPI::returnUNKNOWN;
301                }
302
303                if (vm.count("return"))
304                        retCode = nscapi::plugin_helper::translateReturn(vm["return"].as<std::wstring>());
305
306        } catch (std::exception &e) {
307                msg = _T("Could not parse command: ") + strEx::string_to_wstring(e.what());
308                return NSCAPI::returnCRIT;
309        } catch (...) {
310                msg = _T("Could not parse command: <UNKNOWN EXCEPTION>");
311                return NSCAPI::returnCRIT;
312        }
313        std::list<std::wstring> cmd_args_l(cmd_args.begin(), cmd_args.end());
314
315        worker obj;
316        boost::shared_ptr<boost::thread> t = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&worker::proc, obj, command, cmd_args_l)));
317
318        if (t->timed_join(boost::posix_time::seconds(timeout))) {
319                msg = obj.msg;
320                perf = obj.perf;
321                return obj.code;
322        }
323        t->detach();
324        msg = _T("Thread failed to return within given timeout");
325        return retCode;
326}
327
328NSC_WRAP_DLL();
329NSC_WRAPPERS_MAIN_DEF(gCheckHelpers);
330NSC_WRAPPERS_IGNORE_MSG_DEF();
331NSC_WRAPPERS_HANDLE_CMD_DEF(gCheckHelpers);
Note: See TracBrowser for help on using the repository browser.