source: nscp/include/nscapi/functions.hpp @ 39c73cd

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

2011-08-13 MickeM

  • Added support for command line execution to PythonScript module
  • Readded support for specifying module on command line with --client mode
  • Fixed some issues with the NRPEClient module


2011-08-12 MickeM

  • Finnished (rough) adding back command line exec (with modern API)
  • Fixed so installer uses correct name for dll:s (now Server not Listsener)
  • Property mode set to 100644
File size: 10.1 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#pragma once
22
23#include <boost/math/special_functions.hpp>
24
25#include <string>
26#include <list>
27#include <iostream>
28
29#include <NSCAPI.h>
30#include <charEx.h>
31#include <arrayBuffer.h>
32#include <types.hpp>
33
34#include <unicode_char.hpp>
35#include <strEx.h>
36#include <nscapi/settings_proxy.hpp>
37
38#include <protobuf/plugin.pb.h>
39#include <protobuf/log.pb.h>
40#include <protobuf/exec.pb.h>
41
42using namespace nscp::helpers;
43
44namespace nscapi {
45
46/*
47        class nscapi_exception : public exception {
48                std::string what_;
49        public:
50                nscapi_exception() {}
51                nscapi_exception(std::string what) : what_(what) {}
52                virtual const char* what() const throw() {
53                        return what_;
54                }
55        };
56*/
57        class functions {
58        public:
59                static PluginCommand::Response_Code nagios_to_gpb(int ret) {
60                        if (ret == NSCAPI::returnOK)
61                                return PluginCommand::Response_Code_OK;
62                        if (ret == NSCAPI::returnWARN)
63                                return PluginCommand::Response_Code_WARNING;
64                        if (ret == NSCAPI::returnCRIT)
65                                return PluginCommand::Response_Code_CRITCAL;
66                        return PluginCommand::Response_Code_UNKNOWN;
67                }
68                static ExecuteCommand::Response_Code exec_nagios_to_gpb(int ret) {
69                        if (ret == NSCAPI::returnOK)
70                                return ExecuteCommand::Response_Code_OK;
71                        if (ret == NSCAPI::returnWARN)
72                                return ExecuteCommand::Response_Code_WARNING;
73                        if (ret == NSCAPI::returnCRIT)
74                                return ExecuteCommand::Response_Code_CRITCAL;
75                        return ExecuteCommand::Response_Code_UNKNOWN;
76                }
77                static LogMessage::Message_Level log_to_gpb(NSCAPI::messageTypes ret) {
78                        if (ret == NSCAPI::critical)
79                                return ::LogMessage::Message_Level_LOG_CRITICAL;
80                        if (ret == NSCAPI::debug)
81                                return ::LogMessage::Message_Level_LOG_DEBUG;
82                        if (ret == NSCAPI::error)
83                                return ::LogMessage::Message_Level_LOG_ERROR;
84                        if (ret == NSCAPI::log)
85                                return ::LogMessage::Message_Level_LOG_INFO;
86                        if (ret == NSCAPI::warning)
87                                return ::LogMessage::Message_Level_LOG_WARNING;
88                        return ::LogMessage::Message_Level_LOG_ERROR;
89                }
90                static NSCAPI::messageTypes gpb_to_log(LogMessage::Message_Level ret) {
91                        if (ret == ::LogMessage::Message_Level_LOG_CRITICAL)
92                                return NSCAPI::critical;
93                        if (ret == ::LogMessage::Message_Level_LOG_DEBUG)
94                                return NSCAPI::debug;
95                        if (ret == ::LogMessage::Message_Level_LOG_ERROR)
96                                return NSCAPI::error;
97                        if (ret == ::LogMessage::Message_Level_LOG_INFO)
98                                return NSCAPI::log;
99                        if (ret == ::LogMessage::Message_Level_LOG_WARNING)
100                                return NSCAPI::warning;
101                        return NSCAPI::error;
102                }
103
104                static double trim_to_double(std::wstring s) {
105                        std::wstring::size_type pend = s.find_first_not_of(_T("0123456789,."));
106                        if (pend != std::wstring::npos)
107                                s = s.substr(0,pend);
108                        strEx::replace(s, _T(","), _T("."));
109                        return strEx::stod(s);
110                }
111
112                struct decoded_simple_command_data {
113                        std::wstring command;
114                        std::list<std::wstring> args;
115                        std::vector<std::wstring> args_vector;
116                };
117
118               
119                static decoded_simple_command_data process_simple_command_line_exec_request(const wchar_t* char_command, const std::string &request) {
120                        decoded_simple_command_data data;
121
122                        data.command = char_command;
123                        ExecuteCommand::RequestMessage request_message;
124                        request_message.ParseFromString(request);
125
126                        if (request_message.payload_size() != 1) {
127                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
128                        }
129                        ::ExecuteCommand::Request payload = request_message.payload().Get(0);
130                        for (int i=0;i<payload.arguments_size();i++) {
131                                data.args_vector.push_back(to_wstring(payload.arguments(i)));
132                        }
133                        return data;
134                }
135                static NSCAPI::nagiosReturn process_simple_command_line_exec_result(std::wstring command, NSCAPI::nagiosReturn ret, std::wstring result, std::string &response) {
136                        ExecuteCommand::ResponseMessage response_message;
137                        ::ExecuteCommand::Header* hdr = response_message.mutable_header();
138
139                        hdr->set_type(ExecuteCommand::Header_Type_RESPONSE);
140                        hdr->set_version(ExecuteCommand::Header_Version_VERSION_1);
141
142                        ExecuteCommand::Response *resp = response_message.add_payload();
143                        resp->set_command(to_string(command));
144                        resp->set_message(to_string(result));
145
146                        resp->set_version(ExecuteCommand::Response_Version_VERSION_1);
147                        resp->set_result(exec_nagios_to_gpb(ret));
148                        response_message.SerializeToString(&response);
149                        return ret;
150                }
151
152                static decoded_simple_command_data process_simple_command_request(const wchar_t* char_command, const std::string &request) {
153                        decoded_simple_command_data data;
154
155                        data.command = char_command;
156                        PluginCommand::RequestMessage request_message;
157                        request_message.ParseFromString(request);
158
159                        if (request_message.payload_size() != 1) {
160                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
161                        }
162                        ::PluginCommand::Request payload = request_message.payload().Get(0);
163                        for (int i=0;i<payload.arguments_size();i++) {
164                                data.args.push_back(to_wstring(payload.arguments(i)));
165                        }
166                        return data;
167                }
168                static NSCAPI::nagiosReturn process_simple_command_result(std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf, std::string &response) {
169                        PluginCommand::ResponseMessage response_message;
170                        ::PluginCommand::Header* hdr = response_message.mutable_header();
171
172                        hdr->set_type(PluginCommand::Header_Type_RESPONSE);
173                        hdr->set_version(PluginCommand::Header_Version_VERSION_1);
174
175                        PluginCommand::Response *resp = response_message.add_payload();
176                        resp->set_command(to_string(command));
177                        resp->set_message(to_string(msg));
178                        parse_performance_data(resp, perf);
179
180                        resp->set_version(PluginCommand::Response_Version_VERSION_1);
181                        resp->set_result(nagios_to_gpb(ret));
182                        response_message.SerializeToString(&response);
183                        return ret;
184                }
185                static void parse_performance_data(PluginCommand::Response *resp, std::wstring &perf) {
186
187                        boost::tokenizer<boost::escaped_list_separator<wchar_t>, std::wstring::const_iterator, std::wstring> tok(perf, boost::escaped_list_separator<wchar_t>(L'\\', L' ', L'\''));
188                        BOOST_FOREACH(std::wstring s, tok) {
189                                if (s.size() == 0)
190                                        break;
191                                strEx::splitVector items = strEx::splitV(s, _T(";"));
192                                if (items.size() < 1) {
193                                        ::PluginCommand::PerformanceData* perfData = resp->add_perf();
194                                        perfData->set_type(PluginCommand::PerformanceData_Type_STRING);
195                                        std::pair<std::wstring,std::wstring> fitem = strEx::split(_T(""), _T("="));
196                                        perfData->set_alias("invalid");
197                                        ::PluginCommand::PerformanceData_StringValue* stringPerfData = perfData->mutable_string_value();
198                                        stringPerfData->set_value("invalid performance data");
199                                        break;
200                                }
201
202                                ::PluginCommand::PerformanceData* perfData = resp->add_perf();
203                                perfData->set_type(PluginCommand::PerformanceData_Type_FLOAT);
204                                std::pair<std::wstring,std::wstring> fitem = strEx::split(items[0], _T("="));
205                                perfData->set_alias(to_string(fitem.first));
206                                ::PluginCommand::PerformanceData_FloatValue* floatPerfData = perfData->mutable_float_value();
207
208                                std::wstring::size_type pend = fitem.second.find_first_not_of(_T("0123456789,."));
209                                if (pend == std::wstring::npos) {
210                                        floatPerfData->set_value(trim_to_double(fitem.second.c_str()));
211                                } else {
212                                        floatPerfData->set_value(trim_to_double(fitem.second.substr(0,pend).c_str()));
213                                        floatPerfData->set_unit(to_string(fitem.second.substr(pend)));
214                                }
215                                if (items.size() > 2) {
216                                        floatPerfData->set_warning(trim_to_double(items[1]));
217                                        floatPerfData->set_critical(trim_to_double(items[2]));
218                                }
219                                if (items.size() >= 5) {
220                                        floatPerfData->set_minimum(trim_to_double(items[3]));
221                                        floatPerfData->set_maximum(trim_to_double(items[4]));
222                                }
223                        }
224//                      std::wcout << _T("Converting performance data") << perf << _T(" -- ") << utf8::cvt<std::wstring>(build_performance_data(*resp)) << std::endl;
225                }
226                static std::string build_performance_data(::PluginCommand::Response const &payload) {
227                        std::stringstream ss;
228                        ss.precision(5);
229
230                        bool first = true;
231                        for (int i=0;i<payload.perf_size();i++) {
232                                ::PluginCommand::PerformanceData perfData = payload.perf(i);
233                                if (!first)
234                                        ss << " ";
235                                first = false;
236                                ss << '\'' << perfData.alias() << "'=";
237                                if (perfData.has_float_value()) {
238                                        ::PluginCommand::PerformanceData_FloatValue fval = perfData.float_value();
239
240                                        ss << fval.value();
241                                        if (fval.has_unit())
242                                                ss << fval.unit();
243                                        if (!fval.has_warning())
244                                                continue;
245                                        ss << ";" << fval.warning();
246                                        if (!fval.has_critical())       
247                                                continue;
248                                        ss << ";" << fval.critical();
249                                        if (!fval.has_minimum())
250                                                continue;
251                                        ss << ";" << fval.minimum();
252                                        if (!fval.has_maximum())
253                                                continue;
254                                        ss << ";" << fval.maximum();
255                                }
256                        }
257                        return ss.str();
258                }
259        };
260}
Note: See TracBrowser for help on using the repository browser.