source: nscp/include/nscapi/functions.hpp @ 2c95d22

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

2011-08-14 MickeM

  • Rename Function to Registry in PythonScript API as well as some other function renames
  • Started to clean up the helpers around the API
  • Added support for execute to PythonScripts? to execute commands
  • BUG: just realised that static plugin instances prevent multiple instances :) Will fix but not now as it is not important (for me)...
  • Added initial support for channels to PythonScript Core still lacks support for subscribing to arbitrary channel
  • Property mode set to 100644
File size: 12.3 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 parse_simple_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.push_back(to_wstring(payload.arguments(i)));
132                        }
133                        return data;
134                }
135                static NSCAPI::nagiosReturn create_simple_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
169                static NSCAPI::nagiosReturn process_simple_command_result(std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf, std::string &response) {
170                        PluginCommand::ResponseMessage response_message;
171                        ::PluginCommand::Header* hdr = response_message.mutable_header();
172
173                        hdr->set_type(PluginCommand::Header_Type_RESPONSE);
174                        hdr->set_version(PluginCommand::Header_Version_VERSION_1);
175
176                        PluginCommand::Response *resp = response_message.add_payload();
177                        resp->set_command(to_string(command));
178                        resp->set_message(to_string(msg));
179                        parse_performance_data(resp, perf);
180
181                        resp->set_version(PluginCommand::Response_Version_VERSION_1);
182                        resp->set_result(nagios_to_gpb(ret));
183                        response_message.SerializeToString(&response);
184                        return ret;
185                }
186
187                static void create_simple_exec_request(const std::wstring &command, const std::list<std::wstring> & args, std::string &request) {
188                       
189                        ExecuteCommand::RequestMessage message;
190                        ExecuteCommand::Header *hdr = message.mutable_header();
191                        hdr->set_type(ExecuteCommand::Header_Type_REQUEST);
192                        hdr->set_version(ExecuteCommand::Header_Version_VERSION_1);
193
194                        ExecuteCommand::Request *req = message.add_payload();
195                        req->set_command(to_string(command));
196                        req->set_version(ExecuteCommand::Request_Version_VERSION_1);
197
198                        BOOST_FOREACH(std::wstring s, args)
199                                req->add_arguments(to_string(s));
200
201                        message.SerializeToString(&request);
202                }
203                static void parse_simple_exec_result(const std::string &response, std::list<std::wstring> &result) {
204                        ExecuteCommand::ResponseMessage response_message;
205                        response_message.ParseFromString(response);
206
207                        for (int i=0;i<response_message.payload_size(); i++) {
208                                result.push_back(utf8::cvt<std::wstring>(response_message.payload(i).message()));
209                        }
210                }
211
212
213                static void create_simple_message_request(std::wstring command, NSCAPI::nagiosReturn code, std::wstring &msg, std::wstring &perf, std::string &request) {
214                        PluginCommand::ResponseMessage message;
215                        PluginCommand::Header *hdr = message.mutable_header();
216                        hdr->set_type(PluginCommand::Header_Type_RESPONSE);
217                        hdr->set_version(PluginCommand::Header_Version_VERSION_1);
218
219                        PluginCommand::Response *resp = message.add_payload();
220                        resp->set_command(to_string(command));
221                        resp->set_result(nagios_to_gpb(code));
222                        resp->set_version(PluginCommand::Response_Version_VERSION_1);
223                        resp->set_message(to_string(msg));
224                        parse_performance_data(resp, perf);
225
226                        message.SerializeToString(&request);
227                }
228               
229
230                static void parse_simple_message(std::string &response, std::wstring &msg, std::wstring &perf) {
231                        PluginCommand::ResponseMessage response_message;
232                        response_message.ParseFromString(response);
233
234
235                        if (response_message.payload_size() != 1) {
236                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
237                        }
238                        PluginCommand::Response payload = response_message.payload().Get(0);
239                        msg = utf8::cvt<std::wstring>(payload.message());
240                        perf = utf8::cvt<std::wstring>(build_performance_data(payload));
241                }
242
243                static void parse_performance_data(PluginCommand::Response *resp, std::wstring &perf) {
244                        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'\''));
245                        BOOST_FOREACH(std::wstring s, tok) {
246                                if (s.size() == 0)
247                                        break;
248                                strEx::splitVector items = strEx::splitV(s, _T(";"));
249                                if (items.size() < 1) {
250                                        ::PluginCommand::PerformanceData* perfData = resp->add_perf();
251                                        perfData->set_type(PluginCommand::PerformanceData_Type_STRING);
252                                        std::pair<std::wstring,std::wstring> fitem = strEx::split(_T(""), _T("="));
253                                        perfData->set_alias("invalid");
254                                        ::PluginCommand::PerformanceData_StringValue* stringPerfData = perfData->mutable_string_value();
255                                        stringPerfData->set_value("invalid performance data");
256                                        break;
257                                }
258
259                                ::PluginCommand::PerformanceData* perfData = resp->add_perf();
260                                perfData->set_type(PluginCommand::PerformanceData_Type_FLOAT);
261                                std::pair<std::wstring,std::wstring> fitem = strEx::split(items[0], _T("="));
262                                perfData->set_alias(to_string(fitem.first));
263                                ::PluginCommand::PerformanceData_FloatValue* floatPerfData = perfData->mutable_float_value();
264
265                                std::wstring::size_type pend = fitem.second.find_first_not_of(_T("0123456789,."));
266                                if (pend == std::wstring::npos) {
267                                        floatPerfData->set_value(trim_to_double(fitem.second.c_str()));
268                                } else {
269                                        floatPerfData->set_value(trim_to_double(fitem.second.substr(0,pend).c_str()));
270                                        floatPerfData->set_unit(to_string(fitem.second.substr(pend)));
271                                }
272                                if (items.size() > 2) {
273                                        floatPerfData->set_warning(trim_to_double(items[1]));
274                                        floatPerfData->set_critical(trim_to_double(items[2]));
275                                }
276                                if (items.size() >= 5) {
277                                        floatPerfData->set_minimum(trim_to_double(items[3]));
278                                        floatPerfData->set_maximum(trim_to_double(items[4]));
279                                }
280                        }
281//                      std::wcout << _T("Converting performance data") << perf << _T(" -- ") << utf8::cvt<std::wstring>(build_performance_data(*resp)) << std::endl;
282                }
283                static std::string build_performance_data(::PluginCommand::Response const &payload) {
284                        std::stringstream ss;
285                        ss.precision(5);
286
287                        bool first = true;
288                        for (int i=0;i<payload.perf_size();i++) {
289                                ::PluginCommand::PerformanceData perfData = payload.perf(i);
290                                if (!first)
291                                        ss << " ";
292                                first = false;
293                                ss << '\'' << perfData.alias() << "'=";
294                                if (perfData.has_float_value()) {
295                                        ::PluginCommand::PerformanceData_FloatValue fval = perfData.float_value();
296
297                                        ss << fval.value();
298                                        if (fval.has_unit())
299                                                ss << fval.unit();
300                                        if (!fval.has_warning())
301                                                continue;
302                                        ss << ";" << fval.warning();
303                                        if (!fval.has_critical())       
304                                                continue;
305                                        ss << ";" << fval.critical();
306                                        if (!fval.has_minimum())
307                                                continue;
308                                        ss << ";" << fval.minimum();
309                                        if (!fval.has_maximum())
310                                                continue;
311                                        ss << ";" << fval.maximum();
312                                }
313                        }
314                        return ss.str();
315                }
316        };
317}
Note: See TracBrowser for help on using the repository browser.