]> granicus.if.org Git - icinga2/blob - lib/icinga/pluginutility.cpp
Remove unused includes
[icinga2] / lib / icinga / pluginutility.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "icinga/pluginutility.hpp"
21 #include "icinga/macroprocessor.hpp"
22 #include "base/logger.hpp"
23 #include "base/utility.hpp"
24 #include "base/perfdatavalue.hpp"
25 #include "base/convert.hpp"
26 #include "base/process.hpp"
27 #include "base/objectlock.hpp"
28 #include "base/exception.hpp"
29 #include <boost/algorithm/string/trim.hpp>
30
31 using namespace icinga;
32
33 void PluginUtility::ExecuteCommand(const Command::Ptr& commandObj, const Checkable::Ptr& checkable,
34         const CheckResult::Ptr& cr, const MacroProcessor::ResolverList& macroResolvers,
35         const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros,
36         const std::function<void(const Value& commandLine, const ProcessResult&)>& callback)
37 {
38         Value raw_command = commandObj->GetCommandLine();
39         Dictionary::Ptr raw_arguments = commandObj->GetArguments();
40
41         Value command;
42
43         try {
44                 command = MacroProcessor::ResolveArguments(raw_command, raw_arguments,
45                         macroResolvers, cr, resolvedMacros, useResolvedMacros);
46         } catch (const std::exception& ex) {
47                 String message = DiagnosticInformation(ex);
48
49                 Log(LogWarning, "PluginUtility", message);
50
51                 if (callback) {
52                         ProcessResult pr;
53                         pr.PID = -1;
54                         pr.ExecutionStart = Utility::GetTime();
55                         pr.ExecutionEnd = pr.ExecutionStart;
56                         pr.ExitStatus = 3; /* Unknown */
57                         pr.Output = message;
58                         callback(Empty, pr);
59                 }
60
61                 return;
62         }
63
64         Dictionary::Ptr envMacros = new Dictionary();
65
66         Dictionary::Ptr env = commandObj->GetEnv();
67
68         if (env) {
69                 ObjectLock olock(env);
70                 for (const Dictionary::Pair& kv : env) {
71                         String name = kv.second;
72
73                         Value value = MacroProcessor::ResolveMacros(name, macroResolvers, cr,
74                                 nullptr, MacroProcessor::EscapeCallback(), resolvedMacros,
75                                 useResolvedMacros);
76
77                         if (value.IsObjectType<Array>())
78                                 value = Utility::Join(value, ';');
79
80                         envMacros->Set(kv.first, value);
81                 }
82         }
83
84         if (resolvedMacros && !useResolvedMacros)
85                 return;
86
87         Process::Ptr process = new Process(Process::PrepareCommand(command), envMacros);
88
89         if (checkable->GetCheckTimeout().IsEmpty())
90                 process->SetTimeout(commandObj->GetTimeout());
91         else
92                 process->SetTimeout(checkable->GetCheckTimeout());
93
94         process->SetAdjustPriority(true);
95
96         process->Run(std::bind(callback, command, _1));
97 }
98
99 ServiceState PluginUtility::ExitStatusToState(int exitStatus)
100 {
101         switch (exitStatus) {
102                 case 0:
103                         return ServiceOK;
104                 case 1:
105                         return ServiceWarning;
106                 case 2:
107                         return ServiceCritical;
108                 default:
109                         return ServiceUnknown;
110         }
111 }
112
113 std::pair<String, String> PluginUtility::ParseCheckOutput(const String& output)
114 {
115         String text;
116         String perfdata;
117
118         std::vector<String> lines = output.Split("\r\n");
119
120         for (const String& line : lines) {
121                 size_t delim = line.FindFirstOf("|");
122
123                 if (!text.IsEmpty())
124                         text += "\n";
125
126                 if (delim != String::NPos) {
127                         text += line.SubStr(0, delim);
128
129                         if (!perfdata.IsEmpty())
130                                 perfdata += " ";
131
132                         perfdata += line.SubStr(delim + 1, line.GetLength());
133                 } else {
134                         text += line;
135                 }
136         }
137
138         boost::algorithm::trim(perfdata);
139
140         return std::make_pair(text, perfdata);
141 }
142
143 Array::Ptr PluginUtility::SplitPerfdata(const String& perfdata)
144 {
145         ArrayData result;
146
147         size_t begin = 0;
148         String multi_prefix;
149
150         for (;;) {
151                 size_t eqp = perfdata.FindFirstOf('=', begin);
152
153                 if (eqp == String::NPos)
154                         break;
155
156                 String label = perfdata.SubStr(begin, eqp - begin);
157
158                 if (label.GetLength() > 2 && label[0] == '\'' && label[label.GetLength() - 1] == '\'')
159                         label = label.SubStr(1, label.GetLength() - 2);
160
161                 size_t multi_index = label.RFind("::");
162
163                 if (multi_index != String::NPos)
164                         multi_prefix = "";
165
166                 size_t spq = perfdata.FindFirstOf(' ', eqp);
167
168                 if (spq == String::NPos)
169                         spq = perfdata.GetLength();
170
171                 String value = perfdata.SubStr(eqp + 1, spq - eqp - 1);
172
173                 if (!multi_prefix.IsEmpty())
174                         label = multi_prefix + "::" + label;
175
176                 String pdv;
177                 if (label.FindFirstOf(" ") != String::NPos)
178                         pdv = "'" + label + "'=" + value;
179                 else
180                         pdv = label + "=" + value;
181
182                 result.emplace_back(std::move(pdv));
183
184                 if (multi_index != String::NPos)
185                         multi_prefix = label.SubStr(0, multi_index);
186
187                 begin = spq + 1;
188         }
189
190         return new Array(std::move(result));
191 }
192
193 String PluginUtility::FormatPerfdata(const Array::Ptr& perfdata)
194 {
195         if (!perfdata)
196                 return "";
197
198         std::ostringstream result;
199
200         ObjectLock olock(perfdata);
201
202         bool first = true;
203         for (const Value& pdv : perfdata) {
204                 if (!first)
205                         result << " ";
206                 else
207                         first = false;
208
209                 if (pdv.IsObjectType<PerfdataValue>())
210                         result << static_cast<PerfdataValue::Ptr>(pdv)->Format();
211                 else
212                         result << pdv;
213         }
214
215         return result.str();
216 }