sla: Stupid Rasmus and his needles and haystacks
[ninja.git] / application / models / execute_command.php
blob42bc29d9346d31caa4f7861806ba7b7949cb2447
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
3 /**
4 * Sends external commands to Nagios command FIFO
5 */
6 class Execute_Command_Model extends Model
8 protected $dryrun = false; /**< Set to true to make it not actually do anything */
10 /**
11 * Returns all downtime data. If filter is set,
12 * it can restrict the query to only hosts or only services.
14 protected static function get_downtime_data($filter=false)
16 $ls_filter = array();
17 if ($filter == nagstat::HOST_DOWNTIME)
18 $ls_filter['is_service'] = 0;
19 else if ($filter == nagstat::SERVICE_DOWNTIME)
20 $ls_filter['is_service'] = 1;
21 $ls = Livestatus::instance();
22 $res = $ls->getDowntimes(array('filter' => $ls_filter));
23 return $res;
26 /**
27 * Get the users/systems configured value for this option
28 * @param $setting Option name
30 static function get_setting($setting)
32 # the underscore is an implementation detail ("don't pass this straight
33 # to nagios") that should not be exposed in config/nagdefault.php
34 $setting = 'nagdefault.'.ltrim($setting, '_');
35 $value = config::get($setting, '*', false);
36 return $value;
39 /**
40 * Get all objects for this "param name" (which is almost object type, but not quite)
42 protected function get_object_list($param_name)
44 $ary = array();
45 switch ($param_name) {
46 case 'service':
47 case 'service_description':
48 $ary = Livestatus::instance()->getServices(array('columns' => array('host_name', 'description')));
49 if ($ary) {
50 $ret_ary = array();
51 foreach ($ary as $v) {
52 $ret_ary[] = $v['host_name'].';'.$v['description'];
54 return $ret_ary;
56 break;
57 case 'host_name':
58 $ary = Livestatus::instance()->getHosts(array('columns' => array('name')));
59 break;
60 case 'hostgroup_name':
61 $ary = Livestatus::instance()->getHostgroups(array('columns' => array('name')));
62 break;
63 case 'servicegroup_name':
64 $ary = Livestatus::instance()->getServicegroups(array('columns' => array('name')));
65 break;
67 $res = array();
68 foreach ($ary as $val) {
69 $res[$val['name']] = $val['name'];
72 return $res;
75 /**
76 * Get ids of current comments
78 * @param $command_name Name of the command (determines which id's to get)
79 * @return array(id => object_name);
81 public function get_comment_ids($command_name = 'DEL_HOST_COMMENT')
83 if ($this->dryrun)
84 return array(1);
86 if ($command_name != 'DEL_HOST_COMMENT') {
87 $query = "SELECT comment_id, ".
88 sql::concat('host_name', ';', 'service_description').
89 " AS obj_name FROM comment_tbl WHERE service_description != '' OR service_description is not NULL";
90 } else {
91 $query = 'SELECT comment_id, host_name as objname FROM comment_tbl ' .
92 "WHERE (service_description = '' OR service_description IS NULL)";
95 $result = $this->db->query($query);
96 $ret = array();
97 foreach ($result as $ary) {
98 $ret[$ary->comment_id] = $ary->comment_id;
100 return $ret;
104 * Get all downtime IDs
106 protected function get_downtime_ids($command_name, $defaults=false)
108 $host_name = isset($defaults['host_name']) ? $defaults['host_name'] : false;
109 $service = isset($defaults['service']) ? $defaults['service'] : false;
111 $options = false;
112 $options = array(0 => _('N/A'));
113 $downtime_data = static::get_downtime_data();
114 if ($downtime_data !== false) {
115 foreach ($downtime_data as $data) {
116 if (strstr($command_name, 'HOST_DOWNTIME')) {
117 $options[$data['id']] = _(sprintf("ID: %s, Host '%s' starting @ %s\n", $data['id'], $data['host_name'], date(nagstat::date_format(), $data['start_time'])));
118 } elseif (strstr($command_name, 'SVC_DOWNTIME')) {
119 if (!empty($data['service_description'])){
120 $options[$data['id']] = sprintf("ID: %s, Service '%s' on host '%s' starting @ %s \n", $data['id'], $data['service_description'], $data['host_name'], date(nagstat::date_format(), $data['start_time']));
126 return $options;
130 * Obtain command information
131 * Complete with information and data needed to request input
132 * regarding a particular command.
134 * @param $cmd string The name (or 'id') of the command
135 * @param $defaults array = false Default values for command parameters
136 * @param $dryrun boolean = false Testing variable. Ignore.
137 * @return false|indexed array
139 public function get_command_info($cmd, $defaults = false, $dryrun = false)
141 $this->dryrun = $dryrun;
143 $info = nagioscmd::cmd_info($cmd);
144 # we need the template to get the information we need
145 if (empty($info) || !isset($info['template'])) {
146 return false;
149 $cmd = $info['name'];
151 $raw_params = array_slice(explode(';', $info['template']), 1);
152 $params = array();
153 $ary = false;
154 foreach ($raw_params as $param_name) {
155 # reset between each loop
156 $ary = array();
157 $suffix = substr($param_name, -5);
159 switch ($param_name) {
160 case 'author':
161 $ary = array('type' => 'immutable', 'default' => Auth::instance()->get_user()->username);
162 break;
163 case 'check_attempts':
164 $ary = array('type' => 'int', 'default' => self::get_setting('check_attempts'));
165 break;
166 case 'check_interval':
167 $ary = array('type' => 'int', 'default' => self::get_setting('check_interval'));
168 break;
169 case 'comment':
170 $ary = array('type' => 'string', 'size' => 100, 'default' => self::get_setting('comment'));
171 break;
172 case 'comment_id':
173 $ary = array('type' => 'select', 'options' => $this->get_comment_ids($cmd));
174 if (isset($defaults['com_id'])) {
175 $ary['default'] = $defaults['com_id'];
177 break;
178 case 'delete':
179 $ary = array('type' => 'bool', 'default' => self::get_setting('delete'));
180 break;
181 case 'downtime_id':
182 $ary = array('type' => 'select', 'options' => $this->get_downtime_ids($cmd, $defaults));
183 if (isset($defaults['service']) && is_array($defaults['service'])) {
184 $downtime_data = static::get_downtime_data(nagstat::SERVICE_DOWNTIME);
185 foreach ($downtime_data as $downtime)
186 if (in_array($downtime['host_name'] . ';' . $downtime['service_description'], $defaults['service']))
187 $ary['default'][] = $downtime['id'];
189 if (isset($defaults['host_name']) && is_array($defaults['host_name'])) {
190 $downtime_data = static::get_downtime_data(nagstat::HOST_DOWNTIME);
191 foreach ($downtime_data as $downtime)
192 if (in_array($downtime['host_name'], $defaults['host_name']))
193 $ary['default'][] = $downtime['id'];
195 $ary['name'] = _('Downtime ID');
196 $ary['help'] = help::render('downtime_id');
197 break;
198 case 'trigger_id':
199 $ary = array('type' => 'select', 'options' => $this->get_downtime_ids($cmd, $defaults));
200 $ary['name'] = _('Triggered by');
201 $ary['help'] = help::render('triggered_by');
202 break;
203 case 'duration':
204 $ary = array('type' => 'duration', 'default' => self::get_setting('duration'));
205 $ary['help'] = help::render('duration');
206 break;
207 case 'event_handler_command':
208 # FIXME: stub options
209 $ary = array('mixed' => array('select', 'string'), 'options' => array());
210 break;
211 case 'file_name':
212 $ary = array('type' => 'string');
213 break;
214 case 'fixed':
215 $ary = array('type' => 'bool', 'default' => self::get_setting('fixed'));
216 break;
217 case 'notification_number':
218 $ary = array('type' => 'int', 'default' => 1);
219 break;
220 case 'notify':
221 $ary = array('type' => 'bool', 'default' => self::get_setting('notify'));
222 break;
223 case 'options':
224 $ary = 'skip';
225 break;
226 case 'persistent':
227 $ary = array('type' => 'bool', 'default' => self::get_setting('persistent'));
228 break;
229 case 'plugin_output':
230 $ary = array('type' => 'string', 'size' => 100);
231 break;
232 case 'return_code':
233 $ary = array('type' => 'select', 'options' => array
234 (0 => 'OK', 1 => 'Warning', 2 => 'Critical',
235 3 => 'Unknown'));
236 break;
237 case 'status_code':
238 $ary = array('type' => 'select', 'options' => array
239 (0 => 'Up', 1 => 'Down'));
240 break;
241 case 'sticky':
242 $ary = array('type' => 'bool', 'default' => self::get_setting('sticky'));
243 break;
244 case 'value':
245 $ary = array('type' => 'string', 'size' => 100, 'default' => 'variable=value');
246 break;
247 case 'varname':
248 case 'varvalue':
249 $ary = array('type' => 'string', 'size' => 100);
250 $ary['name'] = _(sprintf('Variable %s', ucfirst(substr($param_name, 3))));
251 break;
252 # nearly all the object link parameters are handled the same
253 # way (more or less), so we just clump them together here
254 case 'service':
255 case 'service_description':
256 $ary['name'] = 'Service';
257 # fallthrough
258 case 'servicegroup_name':
259 case 'contact_name':
260 case 'contactgroup_name':
261 case 'host_name':
262 case 'hostgroup_name':
263 if (!isset($ary['name'])) {
264 $ary['name'] = ucfirst(substr($param_name, 0, -5));
266 case 'timeperiod':
267 if (!isset($ary['name'])) {
268 $ary['name'] = _('Timeperiod');
270 case 'notification_timeperiod':
271 if (!isset($ary['name'])) {
272 $ary['name'] = _('Notification Timeperiod');
274 case 'check_timeperiod':
275 if (!isset($ary['name'])) {
276 $ary['name'] = _('Check Timeperiod');
278 $ary['type'] = 'select';
279 if($defaults) {
280 if(isset($defaults['host_name'])) {
281 if(isset($defaults['service'])) {
282 if(is_array($defaults['service'])) {
283 foreach($defaults['service'] as $service) {
284 if($this->is_authorized_for_obj('services',$service)) {
285 $ary['options']['service'][] = array($service => $service);
288 } elseif($defaults['host_name'] && $defaults['service']) {
289 $ary['options'] = array($defaults['host_name'].";".$defaults['service'] => $defaults['host_name'].";".$defaults['service']);
291 } else {
292 if(is_array($defaults['host_name'])) {
293 foreach($defaults['host_name'] as $host) {
294 if($this->is_authorized_for_obj('hosts',$host)) {
295 $ary['options']['host_name'][] = $host;
298 } elseif($defaults['host_name']) {
299 $ary['options'] = array($defaults['host_name'] => $defaults['host_name']);
302 } elseif(isset($defaults['hostgroup_name']) && $this->is_authorized_for_obj('hostgroups',$defaults['hostgroup_name'])) {
303 $ary['options'] = array($defaults['hostgroup_name'] => $defaults['hostgroup_name']);
304 } elseif(isset($defaults['servicegroup_name']) && $this->is_authorized_for_obj('servicegroups', $defaults['servicegroup_name'])) {
305 $ary['options'] = array($defaults['servicegroup_name'] => $defaults['servicegroup_name']);
308 if(!isset($ary['options'])) {
309 $ary['options'] = $this->get_object_list($param_name, $defaults);
311 if(count($ary['options']) == 1 && (!is_array($ary['options']) || count(current($ary['options'])) == 1)) {
312 // Must check for inner array's length since the same method call is
313 // used by both "single" and "multiple" versions of submitting commands
314 $ary['type'] = 'immutable';
316 break;
317 case 'notification_delay':
318 $ary = array('type' => 'int', 'default' => 5);
319 $ary['name'] = _('Notification delay (in minutes)');
320 break;
321 # same go for *_time parameters
322 case 'check_time':
323 case 'end_time':
324 case 'notification_time':
325 case 'start_time':
326 $ary = array('type' => 'time', 'default' => date(nagstat::date_format(), time()+10));
327 if ($param_name === 'end_time')
328 $ary['default'] = date(nagstat::date_format(), time() + (self::get_setting('duration') * 3600) + 10);
329 break;
332 if ($ary === 'skip')
333 continue;
335 if (!isset($ary['name'])) {
336 if (strpos($param_name, '_') !== false) {
337 $foo = explode('_', $param_name);
338 $name = '';
339 foreach ($foo as $name_part) {
340 $name .= ucfirst($name_part) . ' ';
342 $ary['name'] = trim($name);
343 } else {
344 $ary['name'] = ucfirst($param_name);
348 if (isset($defaults[$param_name])) {
349 if ($param_name === 'service' && isset($defaults['host_name'])) {
350 $ary['default'] = $defaults['host_name'] . ';' . $defaults[$param_name];
351 } else {
352 $ary['default'] = $defaults[$param_name];
356 $params[$param_name] = $ary;
359 $info['params'] = $params;
360 return $info;
364 * Returns true is the object is avalible and authorized, given a table and
365 * a key
367 * @todo This needs to be removed, and replaced and batched where it's called.
368 * @param string $table
369 * @param string $key
370 * @return boolean
372 private function is_authorized_for_obj($table, $key) {
373 return false !== ObjectPool_Model::pool($table)->fetch_by_key($key);