source: nscp/include/nscapi/functions.hpp @ f33c12f

0.4.00.4.10.4.2
Last change on this file since f33c12f was f33c12f, checked in by Michael Medin <michael@…>, 18 months ago
  • Changed so Client interfaces no longer use "simple" interface meaning correct targets are now propagated (ie. calling NRPE -> NSCA will get correct host set automatically) (havent tested this yet, but now it builds at least, will test to night)
  • Property mode set to 100644
File size: 33.6 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#include <net/net.hpp>
34#include <unicode_char.hpp>
35#include <strEx.h>
36#include <nscapi/settings_proxy.hpp>
37
38#include <protobuf/plugin.pb.h>
39
40using namespace nscp::helpers;
41
42namespace nscapi {
43
44        namespace traits {
45
46                template<class T>
47                struct perf_data_consts {
48                        static const T get_valid_perf_numbers();
49                        static const T get_replace_perf_coma_src();
50                        static const T get_replace_perf_coma_tgt();
51                };
52
53                template<>
54                struct perf_data_consts<std::wstring> {
55                        static const std::wstring get_valid_perf_numbers() {
56                                return _T("0123456789,.");
57                        }
58                        static const std::wstring get_replace_perf_coma_src() {
59                                return _T(",");
60                        }
61                        static const std::wstring get_replace_perf_coma_tgt() {
62                                return _T(".");
63                        }
64                };
65                template<>
66                struct perf_data_consts<std::string> {
67                        static const std::string get_valid_perf_numbers() {
68                                return "0123456789,.";
69                        }
70                        static const std::string get_replace_perf_coma_src() {
71                                return ",";
72                        }
73                        static const std::string get_replace_perf_coma_tgt() {
74                                return ".";
75                        }
76                };
77        }
78        class functions {
79        public:
80                static Plugin::Common::ResultCode nagios_status_to_gpb(int ret) {
81                        if (ret == NSCAPI::returnOK)
82                                return Plugin::Common_ResultCode_OK;
83                        if (ret == NSCAPI::returnWARN)
84                                return Plugin::Common_ResultCode_WARNING;
85                        if (ret == NSCAPI::returnCRIT)
86                                return Plugin::Common_ResultCode_CRITCAL;
87                        return Plugin::Common_ResultCode_UNKNOWN;
88                }
89                static int gbp_to_nagios_status(Plugin::Common::ResultCode ret) {
90                        if (ret == Plugin::Common_ResultCode_OK)
91                                return NSCAPI::returnOK;
92                        if (ret == Plugin::Common_ResultCode_WARNING)
93                                return NSCAPI::returnWARN;
94                        if (ret == Plugin::Common_ResultCode_CRITCAL)
95                                return NSCAPI::returnCRIT;
96                        return NSCAPI::returnUNKNOWN;
97                }
98                static Plugin::Common::Status::StatusType status_to_gpb(int ret) {
99                        if (ret == NSCAPI::isSuccess)
100                                return Plugin::Common_Status_StatusType_OK;
101                        return Plugin::Common_Status_StatusType_PROBLEM;
102                }
103                static int gbp_to_status(Plugin::Common::Status::StatusType ret) {
104                        if (ret == Plugin::Common_Status_StatusType_OK)
105                                return NSCAPI::isSuccess;
106                        return NSCAPI::hasFailed;
107                }
108                static Plugin::Common::ResultCode gbp_status_to_gbp_nagios(Plugin::Common::Status::StatusType ret) {
109                        if (ret == Plugin::Common_Status_StatusType_OK)
110                                return Plugin::Common_ResultCode_OK;
111                        return Plugin::Common_ResultCode_UNKNOWN;
112                }
113                static Plugin::Common::Status::StatusType gbp_to_nagios_gbp_status(Plugin::Common::ResultCode ret) {
114                        if (ret == Plugin::Common_ResultCode_UNKNOWN||ret == Plugin::Common_ResultCode_WARNING||ret == Plugin::Common_ResultCode_CRITCAL)
115                                return Plugin::Common_Status_StatusType_CRITICAL;
116                        return Plugin::Common_Status_StatusType_OK;
117                }
118               
119                static Plugin::LogEntry::Entry::Level log_to_gpb(NSCAPI::messageTypes ret) {
120                        if (ret == NSCAPI::critical)
121                                return Plugin::LogEntry_Entry_Level_LOG_CRITICAL;
122                        if (ret == NSCAPI::debug)
123                                return Plugin::LogEntry_Entry_Level_LOG_DEBUG;
124                        if (ret == NSCAPI::error)
125                                return Plugin::LogEntry_Entry_Level_LOG_ERROR;
126                        if (ret == NSCAPI::log)
127                                return Plugin::LogEntry_Entry_Level_LOG_INFO;
128                        if (ret == NSCAPI::warning)
129                                return Plugin::LogEntry_Entry_Level_LOG_WARNING;
130                        return Plugin::LogEntry_Entry_Level_LOG_ERROR;
131                }
132                static NSCAPI::messageTypes gpb_to_log(Plugin::LogEntry::Entry::Level ret) {
133                        if (ret == Plugin::LogEntry_Entry_Level_LOG_CRITICAL)
134                                return NSCAPI::critical;
135                        if (ret == Plugin::LogEntry_Entry_Level_LOG_DEBUG)
136                                return NSCAPI::debug;
137                        if (ret == Plugin::LogEntry_Entry_Level_LOG_ERROR)
138                                return NSCAPI::error;
139                        if (ret == Plugin::LogEntry_Entry_Level_LOG_INFO)
140                                return NSCAPI::log;
141                        if (ret == Plugin::LogEntry_Entry_Level_LOG_WARNING)
142                                return NSCAPI::warning;
143                        return NSCAPI::error;
144                }
145
146
147                template<class T>
148                static double trim_to_double(T s) {
149                        typename T::size_type pend = s.find_first_not_of(nscapi::traits::perf_data_consts<T>::get_valid_perf_numbers());
150                        if (pend != T::npos)
151                                s = s.substr(0,pend);
152                        strEx::replace(s, nscapi::traits::perf_data_consts<T>::get_replace_perf_coma_src(), nscapi::traits::perf_data_consts<T>::get_replace_perf_coma_tgt());
153                        return strEx::stod(s);
154                }
155
156               
157
158                struct decoded_simple_command_data {
159                        std::wstring command;
160                        std::wstring target;
161                        std::list<std::wstring> args;
162                        //std::vector<std::wstring> args_vector;
163                };
164
165
166
167                static void create_simple_header(Plugin::Common::Header* hdr)  {
168                        hdr->set_version(Plugin::Common_Version_VERSION_1);
169                        hdr->set_max_supported_version(Plugin::Common_Version_VERSION_1);
170                        // @todo add additional fields here!
171                }
172
173                //////////////////////////////////////////////////////////////////////////
174
175                struct destination_container {
176                        std::string id;
177                        std::string host;
178                        std::string address;
179                        std::string comment;
180                        std::list<std::string> tags;
181                        typedef std::map<std::string,std::string> data_map;
182                        data_map data;
183
184                        std::string get_protocol() const {
185                                net::url url = get_url();
186                                return url.protocol;
187                        }
188                        bool has_protocol() const {
189                                return !address.empty();
190                        }
191                        net::url get_url(unsigned int port = 80) const {
192                                return net::parse(address, port);
193                        }
194                        static bool to_bool(std::string value) {
195                                if (value.empty())
196                                        return false;
197                                if (value == "true" || value == "1")
198                                        return true;
199                                return false;
200                        }
201                        static int to_int(std::string value, int def = 0) {
202                                if (value.empty())
203                                        return def;
204                                try {
205                                        return boost::lexical_cast<int>(value);
206                                } catch (...) {
207                                        return def;
208                                }
209                        }
210
211                        inline int get_int_data(std::string key, int def = 0) {
212                                return to_int(data[key]);
213                        }
214                        inline bool get_bool_data(std::string key, int def = 0) {
215                                return to_bool(data[key]);
216                        }
217                        inline std::string get_string_data(std::string key) {
218                                return data[key];
219                        }
220                        inline bool has_data(std::string key) {
221                                return data.find(key) != data.end();
222                        }
223
224                        inline net::url get_url(int default_port) {
225                                return net::parse(address, default_port);
226                        }
227                        void set_string_data(std::string key, std::string value) {
228                                data[key] = value;
229                        }
230                        void set_int_data(std::string key, int value) {
231                                data[key] = boost::lexical_cast<std::string>(value);
232                        }
233                        void set_bool_data(std::string key, bool value) {
234                                data[key] = value?"true":"false";
235                        }
236
237                        std::string to_string() {
238                                std::stringstream ss;
239                                ss << "id: " << id;
240                                ss << ", host: " << host;
241                                ss << ", address: " << address;
242//                              ss << ", protocol: " << protocol;
243                                ss << ", comment: " << comment;
244                                int i=0;
245                                BOOST_FOREACH(std::string a, tags) {
246                                        ss << ", tags[" << i++ << "]: " << a;
247                                }
248                                BOOST_FOREACH(const data_map::value_type &kvp, data) {
249                                        ss << ", data[" << kvp.first << "]: " << kvp.second;
250                                }
251                                return ss.str();
252                        }
253
254                        void import(const destination_container &other) {
255                                if (!other.id.empty())
256                                        id = other.id;
257                                if (!other.host.empty())
258                                        host = other.host;
259                                if (!other.address.empty())
260                                        address = other.address;
261//                              if (!other.protocol.empty())
262//                                      protocol = other.protocol;
263                                if (!other.comment.empty())
264                                        comment = other.comment;
265                                BOOST_FOREACH(const std::string &t, other.tags) {
266                                        tags.push_back(t);
267                                }
268                                BOOST_FOREACH(const data_map::value_type &kvp, other.data) {
269                                        data[kvp.first] = kvp.second;
270                                }
271                        }
272                };
273
274                static void add_host(Plugin::Common::Header* hdr, const destination_container &dst)  {
275                        ::Plugin::Common::Host *host = hdr->add_hosts();
276                        if (!dst.id.empty())
277                                host->set_id(dst.id);
278                        if (!dst.host.empty())
279                                host->set_host(dst.host);
280                        if (!dst.address.empty())
281                                host->set_address(dst.address);
282                        if (!dst.has_protocol())
283                                host->set_protocol(dst.get_protocol());
284                        if (!dst.comment.empty())
285                                host->set_comment(dst.comment);
286                        BOOST_FOREACH(const std::string &t, dst.tags) {
287                                host->add_tags(t);
288                        }
289                        BOOST_FOREACH(const destination_container::data_map::value_type &kvp, dst.data) {
290                                ::Plugin::Common_KeyValue* x = host->add_metadata();
291                                x->set_key(kvp.first);
292                                x->set_value(kvp.second);
293                        }
294                }
295
296                static bool parse_destination(const ::Plugin::Common_Header &header, const std::string tag, destination_container &data, const bool expand_meta = false) {
297                        for (int i=0;i<header.hosts_size();++i) {
298                                const ::Plugin::Common::Host &host = header.hosts(i);
299                                if (host.id() == tag) {
300                                        data.id = tag;
301                                        if (!host.host().empty())
302                                                data.host = host.host();
303                                        if (!host.address().empty())
304                                                data.address = host.address();
305                                        if (data.address.empty() && !host.host().empty())
306                                                data.address = host.host();
307//                                      if (!host.protocol().empty())
308//                                              data.protocol = host.protocol();
309                                        if (!host.comment().empty())
310                                                data.comment = host.comment();
311                                        if (expand_meta) {
312                                                for(int j=0;j<host.tags_size(); ++j) {
313                                                        data.tags.push_back(host.tags(j));
314                                                }
315                                                for(int j=0;j<host.metadata_size(); ++j) {
316                                                        data.data[host.metadata(j).key()] = host.metadata(j).value();
317                                                }
318                                        }
319                                        return true;
320                                }
321                        }
322                        return false;
323                }
324
325                //////////////////////////////////////////////////////////////////////////
326
327                static void make_submit_from_query(std::string &message, const std::wstring channel, const std::wstring alias = _T("")) {
328                        Plugin::QueryResponseMessage response;
329                        response.ParseFromString(message);
330                        Plugin::SubmitRequestMessage request;
331                        request.mutable_header()->CopyFrom(response.header());
332                        request.mutable_header()->set_source_id(request.mutable_header()->recipient_id());
333                        request.set_channel(to_string(channel));
334                        for (int i=0;i<response.payload_size();++i) {
335                                request.add_payload()->CopyFrom(response.payload(i));
336                                if (!alias.empty())
337                                        request.mutable_payload(i)->set_alias(to_string(alias));
338                        }
339                        message = request.SerializeAsString();
340                }
341
342                static void make_query_from_exec(std::string &data) {
343                        Plugin::ExecuteResponseMessage exec_response_message;
344                        exec_response_message.ParseFromString(data);
345                        Plugin::QueryResponseMessage query_response_message;
346                        query_response_message.mutable_header()->CopyFrom(exec_response_message);
347                        for (int i=0;i<exec_response_message.payload_size();++i) {
348                                Plugin::ExecuteResponseMessage::Response p = exec_response_message.payload(i);
349                                append_simple_query_response_payload(query_response_message.add_payload(), p.command(), p.result(), p.message());
350                        }
351                        data = query_response_message.SerializeAsString();
352                }
353                static void make_query_from_submit(std::string &data) {
354                        Plugin::SubmitResponseMessage submit_response_message;
355                        submit_response_message.ParseFromString(data);
356                        Plugin::QueryResponseMessage query_response_message;
357                        query_response_message.mutable_header()->CopyFrom(submit_response_message);
358                        for (int i=0;i<submit_response_message.payload_size();++i) {
359                                Plugin::SubmitResponseMessage::Response p = submit_response_message.payload(i);
360                                append_simple_query_response_payload(query_response_message.add_payload(), p.command(), gbp_status_to_gbp_nagios(p.status().status()), p.status().message(), "");
361                        }
362                        data = query_response_message.SerializeAsString();
363                }
364
365                static void make_exec_from_submit(std::string &data) {
366                        Plugin::SubmitResponseMessage submit_response_message;
367                        submit_response_message.ParseFromString(data);
368                        Plugin::ExecuteResponseMessage exec_response_message;
369                        exec_response_message.mutable_header()->CopyFrom(submit_response_message);
370                        for (int i=0;i<submit_response_message.payload_size();++i) {
371                                Plugin::SubmitResponseMessage::Response p = submit_response_message.payload(i);
372                                append_simple_exec_response_payload(exec_response_message.add_payload(), p.command(), gbp_status_to_gbp_nagios(p.status().status()), p.status().message());
373                        }
374                        data = exec_response_message.SerializeAsString();
375                }
376                static void make_exec_from_query(std::string &data) {
377                        Plugin::QueryResponseMessage query_response_message;
378                        query_response_message.ParseFromString(data);
379                        Plugin::ExecuteResponseMessage exec_response_message;
380                        exec_response_message.mutable_header()->CopyFrom(query_response_message);
381                        for (int i=0;i<query_response_message.payload_size();++i) {
382                                Plugin::QueryResponseMessage::Response p = query_response_message.payload(i);
383                                std::string s = build_performance_data(p);
384                                if (!s.empty())
385                                        s = p.message() + "|" + s;
386                                else
387                                        s = p.message();
388                                append_simple_exec_response_payload(exec_response_message.add_payload(), p.command(), p.result(), s);
389                        }
390                        data = exec_response_message.SerializeAsString();
391                }
392
393
394                static void make_return_header(::Plugin::Common_Header *target, const ::Plugin::Common_Header &source) {
395                        target->CopyFrom(source);
396                        target->set_source_id(target->recipient_id());
397                }
398
399                static void create_simple_query_request(std::wstring command, std::vector<std::wstring> arguments, std::string &buffer) {
400                        Plugin::QueryRequestMessage message;
401                        create_simple_header(message.mutable_header());
402
403                        Plugin::QueryRequestMessage::Request *payload = message.add_payload();
404                        payload->set_command(to_string(command));
405
406                        BOOST_FOREACH(std::wstring s, arguments)
407                                payload->add_arguments(to_string(s));
408
409                        message.SerializeToString(&buffer);
410                }
411
412                static void create_simple_submit_request(std::wstring channel, std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf, std::string &buffer) {
413                        Plugin::SubmitRequestMessage message;
414                        create_simple_header(message.mutable_header());
415                        message.set_channel(to_string(channel));
416
417                        Plugin::QueryResponseMessage::Response *payload = message.add_payload();
418                        payload->set_command(to_string(command));
419                        payload->set_message(to_string(msg));
420                        payload->set_result(nagios_status_to_gpb(ret));
421                        if (!perf.empty())
422                                parse_performance_data(payload, perf);
423
424                        message.SerializeToString(&buffer);
425                }
426                static void create_simple_submit_response(std::wstring channel, std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::string &buffer) {
427                        Plugin::SubmitResponseMessage message;
428                        create_simple_header(message.mutable_header());
429                        //message.set_channel(to_string(channel));
430
431                        Plugin::SubmitResponseMessage::Response *payload = message.add_payload();
432                        payload->set_command(utf8::cvt<std::string>(command));
433                        payload->mutable_status()->set_message(to_string(msg));
434                        payload->mutable_status()->set_status(status_to_gpb(ret));
435                        message.SerializeToString(&buffer);
436                }
437                static NSCAPI::errorReturn parse_simple_submit_request(const std::string &request, std::wstring &source, std::wstring &command, std::wstring &msg, std::wstring &perf) {
438                        Plugin::SubmitRequestMessage message;
439                        message.ParseFromString(request);
440
441                        if (message.payload_size() != 1) {
442                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
443                        }
444                        Plugin::QueryResponseMessage::Response payload = message.payload().Get(0);
445                        source = utf8::cvt<std::wstring>(payload.source());
446                        command = utf8::cvt<std::wstring>(payload.command());
447                        msg = utf8::cvt<std::wstring>(payload.message());
448                        perf = utf8::cvt<std::wstring>(build_performance_data(payload));
449                        return gbp_to_nagios_status(payload.result());
450                }
451                /*
452                static NSCAPI::errorReturn parse_simple_submit_request_payload(const Plugin::QueryResponseMessage::Response &payload, std::wstring &alias, std::wstring &command, std::wstring &msg, std::wstring &perf) {
453                        alias = utf8::cvt<std::wstring>(payload.alias());
454                        command = utf8::cvt<std::wstring>(payload.command());
455                        msg = utf8::cvt<std::wstring>(payload.message());
456                        perf = utf8::cvt<std::wstring>(build_performance_data(payload));
457                        return gbp_to_nagios_status(payload.result());
458                }
459                */
460                static int parse_simple_submit_request_payload(const Plugin::QueryResponseMessage::Response &payload, std::wstring &alias, std::wstring &message) {
461                        alias = utf8::cvt<std::wstring>(payload.alias());
462                        message = utf8::cvt<std::wstring>(payload.message());
463                        return gbp_to_nagios_status(payload.result());
464                }
465                static void parse_simple_query_request_payload(const Plugin::QueryRequestMessage::Request &payload, std::wstring &alias, std::wstring &command) {
466                        alias = utf8::cvt<std::wstring>(payload.alias());
467                        command = utf8::cvt<std::wstring>(payload.command());
468                }
469                static NSCAPI::errorReturn parse_simple_submit_response(const std::string &request, std::wstring &response) {
470                        Plugin::SubmitResponseMessage message;
471                        message.ParseFromString(request);
472
473                        if (message.payload_size() != 1) {
474                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
475                        }
476                        ::Plugin::SubmitResponseMessage::Response payload = message.payload().Get(0);
477                        response = to_wstring(payload.mutable_status()->message());
478                        return gbp_to_status(payload.mutable_status()->status());
479                }
480                static NSCAPI::errorReturn parse_simple_submit_response(const std::string &request, std::string response) {
481                        Plugin::SubmitResponseMessage message;
482                        message.ParseFromString(request);
483
484                        if (message.payload_size() != 1) {
485                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
486                        }
487                        ::Plugin::SubmitResponseMessage::Response payload = message.payload().Get(0);
488                        response = payload.mutable_status()->message();
489                        return gbp_to_status(payload.mutable_status()->status());
490                }
491                /*
492                static void create_simple_submit_response(std::wstring msg, int status, std::string &buffer) {
493                        Plugin::SubmitResponseMessage message;
494                        create_simple_header(message.mutable_header());
495
496                        Plugin::SubmitResponseMessage::Response *payload = message.add_payload();
497                        payload->mutable_status()->set_message(to_string(msg));
498                        payload->mutable_status()->set_status(status_to_gpb(status));
499
500                        message.SerializeToString(&buffer);
501                }*/
502
503                static void create_simple_query_request(std::wstring command, std::list<std::wstring> arguments, std::string &buffer) {
504                        Plugin::QueryRequestMessage message;
505                        create_simple_header(message.mutable_header());
506
507                        Plugin::QueryRequestMessage::Request *payload = message.add_payload();
508                        payload->set_command(to_string(command));
509
510                        BOOST_FOREACH(std::wstring s, arguments)
511                                payload->add_arguments(to_string(s));
512
513                        message.SerializeToString(&buffer);
514                }
515                static NSCAPI::nagiosReturn create_simple_query_response_unknown(std::wstring command, std::wstring msg, std::wstring perf, std::string &buffer) {
516                        create_simple_query_response(command, NSCAPI::returnUNKNOWN, msg, perf, buffer);
517                        return NSCAPI::returnUNKNOWN;
518                }
519                static NSCAPI::nagiosReturn create_simple_query_response_unknown(std::wstring command, std::wstring msg, std::string &buffer) {
520                        create_simple_query_response(command, NSCAPI::returnUNKNOWN, msg, _T(""), buffer);
521                        return NSCAPI::returnUNKNOWN;
522                }
523
524                static void create_simple_query_response(std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf, std::string &buffer) {
525                        Plugin::QueryResponseMessage message;
526                        create_simple_header(message.mutable_header());
527
528                        append_simple_query_response_payload(message.add_payload(), command, ret, msg, perf);
529
530                        message.SerializeToString(&buffer);
531                }
532
533               
534                static void append_simple_submit_request_payload(Plugin::QueryResponseMessage::Response *payload, std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf = _T("")) {
535                        payload->set_command(to_string(command));
536                        payload->set_message(to_string(msg));
537                        payload->set_result(nagios_status_to_gpb(ret));
538                        if (!perf.empty())
539                                parse_performance_data(payload, perf);
540                }
541
542                static void append_simple_query_response_payload(Plugin::QueryResponseMessage::Response *payload, std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf) {
543                        payload->set_command(to_string(command));
544                        payload->set_message(to_string(msg));
545                        payload->set_result(nagios_status_to_gpb(ret));
546                        if (!perf.empty())
547                                parse_performance_data(payload, perf);
548                }
549
550                template<class T>
551                static void append_response_payloads(T &target_message, std::string &payload) {
552                        T source_message;
553                        source_message.ParseFromString(payload);
554                        for (int i=0;i<source_message.payload_size();++i)
555                                target_message.add_payload()->CopyFrom(source_message.payload(i));
556                }
557
558                static void append_simple_query_response_payload(Plugin::QueryResponseMessage::Response *payload, std::string command, NSCAPI::nagiosReturn ret, std::string msg, std::string perf = "") {
559                        payload->set_command(to_string(command));
560                        payload->set_message(to_string(msg));
561                        payload->set_result(nagios_status_to_gpb(ret));
562                        if (!perf.empty())
563                                parse_performance_data(payload, perf);
564                }
565/*
566                static void append_simple_exec_response_payload(Plugin::ExecuteResponseMessage::Response *payload, std::string command, Plugin::Common::ResultCode ret, std::string msg) {
567                        payload->set_command(command);
568                        payload->set_message(msg);
569                        payload->set_result(ret);
570                }
571                */
572                static void append_simple_exec_response_payload(Plugin::ExecuteResponseMessage::Response *payload, std::string command, int ret, std::string msg) {
573                        payload->set_command(command);
574                        payload->set_message(msg);
575                        payload->set_result(nagios_status_to_gpb(ret));
576                }
577                /*
578                static void append_simple_submit_response_payload(Plugin::SubmitResponseMessage::Response *payload, std::string command, Plugin::Common::ResultCode ret, std::string msg) {
579                        payload->set_command(command);
580                        payload->mutable_status()->set_status(gbp_to_nagios_gbp_status(ret));
581                        payload->mutable_status()->set_message(msg);
582                }
583                */
584                static void append_simple_submit_response_payload(Plugin::SubmitResponseMessage::Response *payload, std::string command, int ret, std::string msg) {
585                        payload->set_command(command);
586                        payload->mutable_status()->set_status(status_to_gpb(ret));
587                        payload->mutable_status()->set_message(msg);
588                }
589
590
591                static void append_simple_query_request_payload(Plugin::QueryRequestMessage::Request *payload, std::wstring command, std::vector<std::wstring> arguments) {
592                        payload->set_command(to_string(command));
593                        BOOST_FOREACH(const std::wstring &s, arguments) {
594                                payload->add_arguments(to_string(s));
595                        }
596                }
597
598                static void append_simple_exec_request_payload(Plugin::ExecuteRequestMessage::Request *payload, std::wstring command, std::vector<std::wstring> arguments) {
599                        payload->set_command(to_string(command));
600                        BOOST_FOREACH(const std::wstring &s, arguments) {
601                                payload->add_arguments(to_string(s));
602                        }
603                }
604
605
606                static decoded_simple_command_data parse_simple_query_request(const wchar_t* char_command, const std::string &request) {
607                        decoded_simple_command_data data;
608
609                        data.command = char_command;
610                        Plugin::QueryRequestMessage message;
611                        message.ParseFromString(request);
612
613                        if (message.payload_size() != 1) {
614                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
615                        }
616                        ::Plugin::QueryRequestMessage::Request payload = message.payload().Get(0);
617                        for (int i=0;i<payload.arguments_size();i++) {
618                                data.args.push_back(to_wstring(payload.arguments(i)));
619                        }
620                        return data;
621                }
622                static decoded_simple_command_data parse_simple_query_request(const ::Plugin::QueryRequestMessage::Request &payload) {
623                        decoded_simple_command_data data;
624                        data.command = utf8::cvt<std::wstring>(payload.command());
625                        for (int i=0;i<payload.arguments_size();i++) {
626                                data.args.push_back(utf8::cvt<std::wstring>(payload.arguments(i)));
627                        }
628                        return data;
629                }
630
631                static int parse_simple_query_response(const std::string &response, std::wstring &msg, std::wstring &perf) {
632                        Plugin::QueryResponseMessage message;
633                        message.ParseFromString(response);
634
635
636                        if (message.payload_size() == 0) {
637                                return NSCAPI::returnUNKNOWN;
638                        } else if (message.payload_size() > 1) {
639                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
640                        }
641
642                        Plugin::QueryResponseMessage::Response payload = message.payload().Get(0);
643                        msg = utf8::cvt<std::wstring>(payload.message());
644                        perf = utf8::cvt<std::wstring>(build_performance_data(payload));
645                        return gbp_to_nagios_status(payload.result());
646                }
647
648
649                //////////////////////////////////////////////////////////////////////////
650
651                static void create_simple_exec_request(const std::wstring &command, const std::list<std::wstring> & args, std::string &request) {
652                       
653                        Plugin::ExecuteRequestMessage message;
654                        create_simple_header(message.mutable_header());
655
656                        Plugin::ExecuteRequestMessage::Request *payload = message.add_payload();
657                        payload->set_command(to_string(command));
658
659                        BOOST_FOREACH(std::wstring s, args)
660                                payload->add_arguments(to_string(s));
661
662                        message.SerializeToString(&request);
663                }
664                static void create_simple_exec_request(const std::wstring &command, const std::vector<std::wstring> & args, std::string &request) {
665
666                        Plugin::ExecuteRequestMessage message;
667                        create_simple_header(message.mutable_header());
668
669                        Plugin::ExecuteRequestMessage::Request *payload = message.add_payload();
670                        payload->set_command(to_string(command));
671
672                        BOOST_FOREACH(std::wstring s, args)
673                                payload->add_arguments(to_string(s));
674
675                        message.SerializeToString(&request);
676                }
677                static void parse_simple_exec_result(const std::string &response, std::list<std::wstring> &result) {
678                        Plugin::ExecuteResponseMessage message;
679                        message.ParseFromString(response);
680
681                        for (int i=0;i<message.payload_size(); i++) {
682                                result.push_back(utf8::cvt<std::wstring>(message.payload(i).message()));
683                        }
684                }
685                static void parse_simple_exec_result(const std::string &response, std::wstring &result) {
686                        Plugin::ExecuteResponseMessage message;
687                        message.ParseFromString(response);
688
689                        for (int i=0;i<message.payload_size(); i++) {
690                                result += utf8::cvt<std::wstring>(message.payload(i).message());
691                        }
692                }
693
694                template<class T>
695                static int create_simple_exec_response(T command, NSCAPI::nagiosReturn ret, T result, std::string &response) {
696                        Plugin::ExecuteResponseMessage message;
697                        create_simple_header(message.mutable_header());
698
699                        Plugin::ExecuteResponseMessage::Response *payload = message.add_payload();
700                        payload->set_command(to_string(command));
701                        payload->set_message(to_string(result));
702
703                        payload->set_result(nagios_status_to_gpb(ret));
704                        message.SerializeToString(&response);
705                        return ret;
706                }
707                template<class T>
708                static int create_simple_exec_response_unknown(T command, T result, std::string &response) {
709                        Plugin::ExecuteResponseMessage message;
710                        create_simple_header(message.mutable_header());
711
712                        Plugin::ExecuteResponseMessage::Response *payload = message.add_payload();
713                        payload->set_command(to_string(command));
714                        payload->set_message(to_string(result));
715
716                        payload->set_result(nagios_status_to_gpb(NSCAPI::returnUNKNOWN));
717                        message.SerializeToString(&response);
718                        return NSCAPI::returnUNKNOWN;
719                }
720                static decoded_simple_command_data parse_simple_exec_request(const wchar_t* char_command, const std::string &request) {
721                        decoded_simple_command_data data;
722
723                        data.command = char_command;
724                        Plugin::ExecuteRequestMessage message;
725                        message.ParseFromString(request);
726                        if (message.has_header())
727                                data.target = utf8::cvt<std::wstring>(message.header().recipient_id());
728
729                        if (message.payload_size() != 1) {
730                                throw nscapi_exception(_T("Whoops, invalid payload size (for now)"));
731                        }
732                        Plugin::ExecuteRequestMessage::Request payload = message.payload().Get(0);
733                        for (int i=0;i<payload.arguments_size();i++) {
734                                data.args.push_back(to_wstring(payload.arguments(i)));
735                        }
736                        return data;
737                }
738                static decoded_simple_command_data parse_simple_exec_request_payload(const Plugin::ExecuteRequestMessage::Request &payload) {
739                        decoded_simple_command_data data;
740                        data.command = utf8::cvt<std::wstring>(payload.command());
741                        for (int i=0;i<payload.arguments_size();i++) {
742                                data.args.push_back(utf8::cvt<std::wstring>(payload.arguments(i)));
743                        }
744                        return data;
745                }
746
747
748                //////////////////////////////////////////////////////////////////////////
749
750                template<class T, class U>
751                struct tokenizer_data {
752                        boost::escaped_list_separator<U> separator;     // \\, ' ', \'
753                        T perf_item_splitter;                                           // ;
754                        T perf_equal_sign;                                                      // =
755                        T perf_valid_number;                                            // 0123456789.,
756
757                };
758
759                template<class T, class U>
760                static void parse_performance_data(Plugin::QueryResponseMessage::Response *payload, T &perf, tokenizer_data<T, U> tokenizer_data) {
761                        boost::tokenizer<boost::escaped_list_separator<U>, typename T::const_iterator, T> tok(perf, tokenizer_data.separator);
762                        BOOST_FOREACH(const T s, tok) {
763                                if (s.size() == 0)
764                                        break;
765                                std::vector<T> items = strEx::splitV(s, tokenizer_data.perf_item_splitter);
766                                if (items.size() < 1) {
767                                        Plugin::Common::PerformanceData* perfData = payload->add_perf();
768                                        perfData->set_type(Plugin::Common_DataType_STRING);
769                                        std::pair<T,T> fitem = strEx::split(T(), tokenizer_data.perf_equal_sign);
770                                        perfData->set_alias("invalid");
771                                        Plugin::Common_PerformanceData_StringValue* stringPerfData = perfData->mutable_string_value();
772                                        stringPerfData->set_value("invalid performance data");
773                                        break;
774                                }
775
776                                Plugin::Common::PerformanceData* perfData = payload->add_perf();
777                                perfData->set_type(Plugin::Common_DataType_FLOAT);
778                                std::pair<T,T> fitem = strEx::split(items[0], tokenizer_data.perf_equal_sign);
779                                perfData->set_alias(to_string(fitem.first));
780                                Plugin::Common_PerformanceData_FloatValue* floatPerfData = perfData->mutable_float_value();
781
782                                typename T::size_type pend = fitem.second.find_first_not_of(tokenizer_data.perf_valid_number);
783                                if (pend == T::npos) {
784                                        floatPerfData->set_value(trim_to_double(fitem.second));
785                                } else {
786                                        floatPerfData->set_value(trim_to_double(fitem.second.substr(0,pend)));
787                                        floatPerfData->set_unit(to_string(fitem.second.substr(pend)));
788                                }
789                                if (items.size() > 2) {
790                                        floatPerfData->set_warning(trim_to_double(items[1]));
791                                        floatPerfData->set_critical(trim_to_double(items[2]));
792                                }
793                                if (items.size() >= 5) {
794                                        floatPerfData->set_minimum(trim_to_double(items[3]));
795                                        floatPerfData->set_maximum(trim_to_double(items[4]));
796                                }
797                        }
798                }
799                static void parse_performance_data(Plugin::QueryResponseMessage::Response *payload, std::wstring &perf) {
800                        typedef std::wstring t_string;
801                        typedef wchar_t t_char;
802                        tokenizer_data<t_string, t_char> data;
803                        data.separator = boost::escaped_list_separator<t_char>(L'\\', L' ', L'\'');
804                        data.perf_equal_sign = _T("=");
805                        data.perf_item_splitter = _T(";");
806                        data.perf_valid_number = _T("0123456789,.");
807                        parse_performance_data<t_string, t_char>(payload, perf, data);
808                }
809                static void parse_performance_data(Plugin::QueryResponseMessage::Response *payload, std::string &perf) {
810                        typedef std::string t_string;
811                        typedef char t_char;
812                        tokenizer_data<t_string, t_char> data;
813                        data.separator = boost::escaped_list_separator<t_char>('\\', ' ', '\'');
814                        data.perf_equal_sign = "=";
815                        data.perf_item_splitter = ";";
816                        data.perf_valid_number = "0123456789,.";
817                        parse_performance_data<t_string, t_char>(payload, perf, data);
818                }
819
820                static std::string build_performance_data(Plugin::QueryResponseMessage::Response const &payload) {
821                        std::stringstream ss;
822                        ss.precision(5);
823
824                        bool first = true;
825                        for (int i=0;i<payload.perf_size();i++) {
826                                Plugin::Common::PerformanceData perfData = payload.perf(i);
827                                if (!first)
828                                        ss << " ";
829                                first = false;
830                                ss << '\'' << perfData.alias() << "'=";
831                                if (perfData.has_float_value()) {
832                                        Plugin::Common_PerformanceData_FloatValue fval = perfData.float_value();
833
834                                        ss << fval.value();
835                                        if (fval.has_unit())
836                                                ss << fval.unit();
837                                        if (!fval.has_warning())
838                                                continue;
839                                        ss << ";" << fval.warning();
840                                        if (!fval.has_critical())       
841                                                continue;
842                                        ss << ";" << fval.critical();
843                                        if (!fval.has_minimum())
844                                                continue;
845                                        ss << ";" << fval.minimum();
846                                        if (!fval.has_maximum())
847                                                continue;
848                                        ss << ";" << fval.maximum();
849                                }
850                        }
851                        return ss.str();
852                }
853        };
854}
Note: See TracBrowser for help on using the repository browser.