]> granicus.if.org Git - icinga2/blob - components/livestatus/commandstable.cpp
Livestatus: Add command custom variables.
[icinga2] / components / livestatus / commandstable.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org)    *
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 "livestatus/commandstable.h"
21 #include "icinga/icingaapplication.h"
22 #include "icinga/checkcommand.h"
23 #include "icinga/eventcommand.h"
24 #include "icinga/notificationcommand.h"
25 #include "icinga/compatutility.h"
26 #include "base/dynamictype.h"
27 #include "base/objectlock.h"
28 #include "base/convert.h"
29 #include <boost/foreach.hpp>
30 #include <boost/algorithm/string/replace.hpp>
31
32 using namespace icinga;
33
34 CommandsTable::CommandsTable(void)
35 {
36         AddColumns(this);
37 }
38
39 void CommandsTable::AddColumns(Table *table, const String& prefix,
40     const Column::ObjectAccessor& objectAccessor)
41 {
42         table->AddColumn(prefix + "name", Column(&CommandsTable::NameAccessor, objectAccessor));
43         table->AddColumn(prefix + "line", Column(&CommandsTable::LineAccessor, objectAccessor));
44         table->AddColumn(prefix + "custom_variable_names", Column(&CommandsTable::CustomVariableNamesAccessor, objectAccessor));
45         table->AddColumn(prefix + "custom_variable_values", Column(&CommandsTable::CustomVariableValuesAccessor, objectAccessor));
46         table->AddColumn(prefix + "custom_variables", Column(&CommandsTable::CustomVariablesAccessor, objectAccessor));
47 }
48
49 String CommandsTable::GetName(void) const
50 {
51         return "command";
52 }
53
54 void CommandsTable::FetchRows(const AddRowFunction& addRowFn)
55 {
56         BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects<CheckCommand>()) {
57                 addRowFn(object);
58         }
59         BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects<EventCommand>()) {
60                 addRowFn(object);
61         }
62         BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects<NotificationCommand>()) {
63                 addRowFn(object);
64         }
65 }
66
67 Value CommandsTable::NameAccessor(const Value& row)
68 {
69         String buf;
70         Command::Ptr command = static_cast<Command::Ptr>(row);
71         
72         if (!command)
73                 return Empty;
74
75         if (command->GetType() == DynamicType::GetByName("CheckCommand"))
76                 buf += "check_";
77         if (command->GetType() == DynamicType::GetByName("NotificationCommand"))
78                 buf += "notification_";
79         if (command->GetType() == DynamicType::GetByName("EventCommand"))
80                 buf += "event_";
81
82         buf += command->GetName();
83
84         return buf;
85 }
86
87 Value CommandsTable::LineAccessor(const Value& row)
88 {
89         String buf;
90         Command::Ptr command = static_cast<Command::Ptr>(row);
91         
92         if (!command)
93                 return Empty;
94
95         Value commandLine = command->GetCommandLine();
96
97         if (commandLine.IsObjectType<Array>()) {
98                 Array::Ptr args = commandLine;
99
100                 ObjectLock olock(args);
101                 String arg;
102                 BOOST_FOREACH(arg, args) {
103                         // This is obviously incorrect for non-trivial cases.
104                         String argitem = " \"" + arg + "\"";
105                         boost::algorithm::replace_all(argitem, "\n", "\\n");
106                         buf += argitem;
107                 }
108         } else if (!commandLine.IsEmpty()) {
109                 String args = Convert::ToString(commandLine);
110                 boost::algorithm::replace_all(args, "\n", "\\n");
111                 buf += args;
112         } else {
113                 buf += "<internal>";
114         }
115
116         return buf;
117 }
118
119 Value CommandsTable::CustomVariableNamesAccessor(const Value& row)
120 {
121         Command::Ptr command = static_cast<Command::Ptr>(row);
122
123         if (!command)
124                 return Empty;
125
126         Dictionary::Ptr vars;
127
128         {
129                 ObjectLock olock(command);
130                 vars = CompatUtility::GetCustomAttributeConfig(command);
131         }
132
133         if (!vars)
134                 return Empty;
135
136         Array::Ptr cv = make_shared<Array>();
137
138         String key;
139         Value value;
140         BOOST_FOREACH(tie(key, value), vars) {
141                 cv->Add(key);
142         }
143
144         return cv;
145 }
146
147 Value CommandsTable::CustomVariableValuesAccessor(const Value& row)
148 {
149         Command::Ptr command = static_cast<Command::Ptr>(row);
150
151         if (!command)
152                 return Empty;
153
154         Dictionary::Ptr vars;
155
156         {
157                 ObjectLock olock(command);
158                 vars = CompatUtility::GetCustomAttributeConfig(command);
159         }
160
161         if (!vars)
162                 return Empty;
163
164         Array::Ptr cv = make_shared<Array>();
165
166         String key;
167         Value value;
168         BOOST_FOREACH(tie(key, value), vars) {
169                 cv->Add(value);
170         }
171
172         return cv;
173 }
174
175 Value CommandsTable::CustomVariablesAccessor(const Value& row)
176 {
177         Command::Ptr command = static_cast<Command::Ptr>(row);
178
179         if (!command)
180                 return Empty;
181
182         Dictionary::Ptr vars;
183
184         {
185                 ObjectLock olock(command);
186                 vars = CompatUtility::GetCustomAttributeConfig(command);
187         }
188
189         if (!vars)
190                 return Empty;
191
192         Array::Ptr cv = make_shared<Array>();
193
194         String key;
195         Value value;
196         BOOST_FOREACH(tie(key, value), vars) {
197                 Array::Ptr key_val = make_shared<Array>();
198                 key_val->Add(key);
199                 key_val->Add(value);
200                 cv->Add(key_val);
201         }
202
203         return cv;
204 }