Merge branch 'maint/7.0'
[ninja.git] / application / controllers / command.php
blob591e40461b9de2b0f98b27c62e79b5d7ae2de131
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3 * CMD controller
5 * Requires authentication. See the helper nagioscmd for more info.
7 * op5, and the op5 logo are trademarks, servicemarks, registered servicemarks
8 * or registered trademarks of op5 AB.
9 * All other trademarks, servicemarks, registered trademarks, and registered
10 * servicemarks mentioned herein may be the property of their respective owner(s).
11 * The information contained herein is provided AS IS with NO WARRANTY OF ANY
12 * KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A
13 * PARTICULAR PURPOSE.
15 class Command_Controller extends Authenticated_Controller
17 private $command_id = false;
18 private $cmd_params = array();
19 private $csrf_token = false;
20 /**
21 * @var int = 300, if the starting time of a scheduled downtime is
22 * older than this many seconds, it's considered to have been added retrospectively
24 private $grace_time_in_s = 300;
26 /**
27 * Initializes a page with the correct view, java-scripts and css
28 * @param $view The name of the page we want to print
30 protected function init_page($view)
32 $this->template->content = $this->add_view($view);
33 $this->template->disable_refresh = true;
36 /**
37 * @param string $submitted_start_time (Y-m-d H:i:s)
38 * @param string $submitted_end_time (Y-m-d H:i:s)
39 * @return true | string (string = error message)
41 private function _validate_dates($submitted_start_time, $submitted_end_time) {
42 $start_time = nagstat::timestamp_format(nagstat::date_format(), $submitted_start_time);
43 $end_time = nagstat::timestamp_format(nagstat::date_format(), $submitted_end_time);
44 $errors = array();
45 if(!$start_time || !$end_time) {
46 if(!$start_time && !$end_time) {
47 return "Neither of your submitted dates are valid, please <a href='javascript:history.back();'>adjust them</a>";
48 } else {
49 return sprintf("%s is not a valid date, please <a href='javascript:history.back();'>adjust it</a>", $start_time ? $submitted_end_time : $submitted_start_time);
52 if($start_time > $end_time) {
53 return sprintf("The downtime can not end before it starts. Please <a href='javascript:history.back();'>adjust it</a>", $submitted_start_time);
55 return true;
58 /**
59 * Create a standard checkbox item
60 * @param $description The user visible text for this option
61 * @param $name The internal name for this option
62 * @return array suitable for passing to the request template
64 protected function cb($description, $name)
66 $value = Execute_Command_Model::get_setting($name);
67 return array('type' => 'checkbox', 'name' => $description, 'default' => $value);
70 /**
71 * Request a command to be submitted
72 * This method prints input fields to be selected for the
73 * named command.
74 * @param $name The requested command to run
75 * @param $parameters The parameters (host_name etc) for the command
77 public function submit($cmd = false, $params=false)
79 $this->init_page('command/request');
80 $this->template->js[] = $this->add_path('command/js/command.js');
82 if ($cmd === false) {
83 $cmd = $this->input->get('cmd_typ');
86 if ($params === false) {
87 $params = $_GET;
90 if (($auth_check = nagioscmd::is_authorized_for($params)) !== true)
91 return $this->unauthorized($auth_check);
93 $this->template->content->cmd_typ = $cmd;
95 $command = new Execute_Command_Model;
96 $info = $command->get_command_info($cmd, $params);
97 $param = $info['params'];
98 switch ($cmd) {
99 case 'DEL_HOST_COMMENT':
100 case 'DEL_SVC_COMMENT':
101 $param['comment_id']['type'] = 'immutable';
102 break;
103 case 'SCHEDULE_HOST_CHECK':
104 case 'SCHEDULE_SVC_CHECK':
105 case 'SCHEDULE_HOST_SVC_CHECKS':
106 $param['_force'] = $this->cb(_('Force Check'), '_force');
107 break;
109 case 'PROCESS_HOST_CHECK_RESULT':
110 case 'PROCESS_SERVICE_CHECK_RESULT':
111 $param['_perfdata'] = array
112 ('type' => 'string',
113 'size' => 100,
114 'name' => _('Performance data'));
115 break;
117 case 'SCHEDULE_HOST_DOWNTIME':
118 $this->template->inline_js = "grace_time_in_s = '$this->grace_time_in_s'";
119 $this->template->js[] = $this->add_path('command/js/schedule_downtime.js');
120 $param['_child-hosts'] = array
121 ('type' => 'select',
122 'options' => array
123 ('none' => _('Do nothing'),
124 'triggered' => _('Schedule triggered downtime'),
125 'fixed' => _('Schedule fixed downtime')),
126 'default' => 'triggered',
127 'name' => _('Child Hosts'));
128 # fallthrough
129 case 'SCHEDULE_HOSTGROUP_HOST_DOWNTIME':
130 break;
131 case 'SCHEDULE_SVC_DOWNTIME':
132 $this->template->inline_js = "grace_time_in_s = '$this->grace_time_in_s'";
133 $this->template->js[] = $this->add_path('command/js/schedule_downtime.js');
134 break;
136 case 'SEND_CUSTOM_SVC_NOTIFICATION':
137 case 'SEND_CUSTOM_HOST_NOTIFICATION':
138 $param['_broadcast'] = $this->cb(_('Broadcast'), '_broadcast');
139 $param['_force'] = $this->cb(_('Force notification'), '_force');
140 $param['_increment'] = $this->cb(_('Increment notification number'), '_increment');
141 break;
143 case 'ENABLE_HOST_SVC_CHECKS':
144 case 'DISABLE_HOST_SVC_CHECKS':
145 case 'ENABLE_HOSTGROUP_SVC_CHECKS':
146 case 'DISABLE_HOSTGROUP_SVC_CHECKS':
147 case 'ENABLE_SERVICEGROUP_SVC_CHECKS':
148 case 'DISABLE_SERVICEGROUP_SVC_CHECKS':
149 $en_dis = $cmd{0} === 'E' ? _('Enable') : _('Disable');
150 $param['_host-too'] = $this->cb(sprintf(_('%s checks for host too'), $en_dis), '_host-too');
151 break;
153 case 'ENABLE_HOST_CHECK':
154 case 'DISABLE_HOST_CHECK':
155 $en_dis = $cmd{0} === 'E' ? _('Enable') : _('Disable');
156 $param['_services-too'] = $this->cb(sprintf(_('%s checks for services too'), $en_dis), '_services-too');
157 break;
159 case 'ENABLE_HOST_SVC_NOTIFICATIONS':
160 case 'DISABLE_HOST_SVC_NOTIFICATIONS':
161 $en_dis = $cmd{0} === 'E' ? _('Enable') : _('Disable');
162 $param['_host-too'] = $this->cb(sprintf(_('%s notifications for host too'), $en_dis), '_host-too');
163 break;
165 case 'ACKNOWLEDGE_HOST_PROBLEM':
166 $param['_services-too'] = $this->cb(_('Acknowledge any problems on services too'), '_services-too');
167 break;
168 case 'REMOVE_HOST_ACKNOWLEDGEMENT':
169 $param['_services-too'] = $this->cb(_('Remove any acknowledgements on services too'), '_services-too');
170 break;
171 case 'NACOMA_DEL_SERVICE':
172 $res = array();
173 foreach ($params['service'] as $service) {
174 if (($hg = nacoma::getHostgroupForService($service)))
175 $res[$service] = $hg;
178 if ($res) {
179 $info['brief'] = ngettext(
180 "You've selected a service that is saved on a hostgroup",
181 "You've selected services that are saved on hostgroups", count($res));;
182 $info['description'] = '<ul>';
183 foreach ($res as $svc => $hg) {
184 $info['description'] .= sprintf(_('<li>%s is saved on %s</li>'), $svc, $hg);
186 $info['description'] .= '</ul><p>'.ngettext(
187 'Deleting it will delete it from all hosts in the hostgroup. Are you sure? You might instead want to create a better service directly on the host.',
188 'Deleting them will delete them from all the hosts in the hostgroup. Are you sure? You might instead want to create better services directly on the affected hosts.', count($res)).'</p>';
189 break;
191 case 'NACOMA_DEL_HOST':
192 return $this->commit($cmd, $params);
193 break;
194 default:
195 break;
197 $info['params'] = $param;
199 $this->template->toolbar = new Toolbar_Controller( _( "Command" ), _( "Submit" ) );
200 $this->template->content->info = $info;
201 return $info;
204 protected function schedule_retrospectively($selector_type, $target_type, $obj_names, $start_time, $end_time, $comment)
206 $start_time = nagstat::timestamp_format(nagstat::date_format(), $start_time);
207 $end_time = nagstat::timestamp_format(nagstat::date_format(), $end_time);
208 $now = time();
210 if ($start_time + $this->grace_time_in_s >= $now)
211 return;
213 if (!is_array($obj_names))
214 $obj_names = array($obj_names);
216 // Some Assembly Required
217 if ($selector_type != $target_type) {
218 $ls = Livestatus::instance();
219 $individual_objs = array();
220 if ($target_type === 'service' && $selector_type === 'servicegroup') {
221 foreach ($obj_names as $gname) {
222 foreach ($ls->getServices(array('filter' => array('groups' => array('>=' => $gname)), 'columns' => array('host_name', 'description'))) as $row) {
223 $individual_objs[] = $row['host_name'].';'.$row['description'];
227 else if ($target_type === 'service' && $selector_type === 'hostgroup') {
228 foreach ($obj_names as $gname) {
229 foreach ($ls->getServices(array('filter' => array('host_groups' => array('>=' => $gname)), 'columns' => array('host_name', 'description'))) as $row) {
230 $individual_objs[] = $row['host_name'].';'.$row['description'];
234 else if ($target_type === 'host' && $selector_type === 'hostgroup') {
235 foreach ($obj_names as $gname) {
236 foreach ($ls->getHosts(array('filter' => array('groups' => array('>=' => $gname)), 'columns' => array('name'))) as $row) {
237 $individual_objs[$row['name']] = 1;
240 $individual_objs = array_keys($individual_objs);
242 else if ($target_type === 'host' && $selector_type === 'servicegroup') {
243 foreach ($obj_names as $gname) {
244 foreach ($ls->getServices(array('filter' => array('groups' => array('>=' => $gname)), 'columns' => array('host_name'))) as $row) {
245 $individual_objs[$row['host_name']] = 1;
248 $individual_objs = array_keys($individual_objs);
250 else if ($target_type === 'service' && $selector_type === 'host') {
251 foreach ($obj_names as $hname) {
252 foreach ($ls->getServices(array('filter' => array('host_name' => $hname), 'columns' => array('host_name', 'description'))) as $row) {
253 $individual_objs[] = $row['host_name'].';'.$row['description'];
257 $obj_names = $individual_objs;
260 $db = Database::instance();
261 foreach ($obj_names as $obj_name) {
262 if ($target_type == 'service') {
263 list($host_name, $service_desc) = explode(';', $obj_name);
264 $host_name = $db->escape($host_name);
265 $service_desc = $db->escape($service_desc);
267 else {
268 $host_name = $db->escape($obj_name);
269 $service_desc = "''";
271 $start_msg = $db->escape(ucfirst($selector_type)." has entered a period of retroactively added scheduled downtime, reported by '".Auth::instance()->get_user()->username."', reason: '".$comment."'");
272 $end_msg = $db->escape(ucfirst($selector_type)." has exited a period of retroactively added scheduled downtime, reported by '".Auth::instance()->get_user()->username."', reason: '".$comment."'");
274 $db->query("INSERT INTO report_data(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($start_time, 1103, $host_name, $service_desc, 1, $start_msg)");
275 $db->query("INSERT INTO report_data_extras(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($start_time, 1103, $host_name, $service_desc, 1, $start_msg)");
276 $db->query("INSERT INTO report_data(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($end_time, 1104, $host_name, $service_desc, 0, $end_msg)");
277 $db->query("INSERT INTO report_data_extras(timestamp, event_type, host_name, service_description, downtime_depth, output) VALUES ($end_time, 1104, $host_name, $service_desc, 0, $end_msg)");
282 * Takes the command parameters given by the "submit" function
283 * and creates a Nagios command that gets fed to Nagios through
284 * the query handler.
286 public function commit($cmd = false, $param=false)
288 if (!$cmd) {
289 if(!isset($_REQUEST['cmd_typ']))
290 return $this->unauthorized();
291 $cmd = $_REQUEST['cmd_typ'];
294 if (!$param)
295 $param = isset($_REQUEST['cmd_param']) ? $_REQUEST['cmd_param'] : array();
297 $this->init_page('command/commit');
298 $this->template->content->cmd_typ = $cmd;
300 $nagios_commands = array();
301 if (($auth_check = nagioscmd::is_authorized_for($param, $cmd)) !== true)
302 return $this->unauthorized($auth_check);
304 $param['author'] = Auth::instance()->get_user()->username;
306 if (isset($param['comment']) && trim($param['comment'])=='') {
307 # comments shouldn't ever be empty
308 $this->template->content->result = false;
309 $this->template->content->error = _("Required field 'Comment' was not entered").'<br />'.
310 _(sprintf('Go %s back %s and verify that you entered all required information correctly', '<a href="javascript:history.back();">', '</a>'));
311 return false;
313 $fallthrough = false;
314 switch ($cmd) {
315 case 'SCHEDULE_HOST_CHECK':
316 case 'SCHEDULE_SVC_CHECK':
317 case 'SCHEDULE_HOST_SVC_CHECKS':
318 if (!empty($param['_force'])) {
319 unset($param['force']);
320 $cmd = 'SCHEDULE_FORCED' . substr($cmd, strlen("SCHEDULE"));
322 break;
324 case 'PROCESS_HOST_CHECK_RESULT':
325 case 'PROCESS_SERVICE_CHECK_RESULT':
326 if (!empty($param['_perfdata']) && !empty($param['plugin_output'])) {
327 $param['plugin_output'] .= "|".$param['_perfdata'];
328 unset($param['perfdata']);
330 break;
332 case 'SCHEDULE_HOST_DOWNTIME':
333 $date_validation_result = $this->_validate_dates($param['start_time'], $param['end_time']);
334 if($date_validation_result !== true) {
335 $this->template->content->result = false;
336 $this->template->content->error = $date_validation_result;
337 return;
339 if (!empty($param['_child-hosts']) && $param['_child-hosts'] != 'none') {
340 $what = $param['_child-hosts'];
341 unset($param['_child-hosts']);
342 if ($what === 'triggered') {
343 $cmd = 'SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME';
344 } elseif ($what === 'fixed') {
345 $cmd = 'SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME';
348 if(isset($param['fixed']) && $param['fixed']) {
349 $this->schedule_retrospectively('host', 'host', $param['host_name'], $param['start_time'], $param['end_time'], $param['comment']);
351 $fallthrough = true;
352 # fallthrough to services-too handling
353 case 'SCHEDULE_HOSTGROUP_HOST_DOWNTIME':
354 if(!$fallthrough && isset($param['fixed']) && $param['fixed']) {
355 $this->schedule_retrospectively('hostgroup', 'host', $param['hostgroup_name'], $param['start_time'], $param['end_time'], $param['comment']);
357 if (!empty($param['_services-too'])) {
358 unset($param['_services-too']);
359 if ($fallthrough) {
360 $nagios_commands = array_merge($this->_build_command('SCHEDULE_HOST_SVC_DOWNTIME', $param), $nagios_commands);
361 } else {
362 $nagios_commands = array_merge($this->_build_command('SCHEDULE_HOSTGROUP_SVC_DOWNTIME', $param), $nagios_commands);
364 if(isset($param['fixed']) && $param['fixed']) {
365 $grouptype = $fallthrough?'host':'hostgroup';
366 $this->schedule_retrospectively($grouptype, 'service', $param[$grouptype.'_name'], $param['start_time'], $param['end_time'], $param['comment']);
369 break;
371 case 'SEND_CUSTOM_HOST_NOTIFICATION':
372 case 'SEND_CUSTOM_SVC_NOTIFICATION':
373 $options = 0;
374 if (isset($param['_broadcast'])) {
375 unset($param['_broadcast']);
376 $options |= 1;
378 if (isset($param['_force'])) {
379 unset($param['_force']);
380 $options |= 2;
382 if (isset($param['_increment'])) {
383 unset($param['_increment']);
384 $options |= 4;
387 $param['options'] = $options;
388 break;
390 case 'ENABLE_HOST_SVC_CHECKS':
391 case 'DISABLE_HOST_SVC_CHECKS':
392 $xcmd = $cmd{0} === 'D' ? 'DISABLE' : 'ENABLE';
393 $xcmd .= '_HOST_CHECK';
394 if (!empty($param['_host-too']))
395 $nagios_commands = $this->_build_command($xcmd, $param);
396 break;
398 case 'ENABLE_HOST_CHECK':
399 case 'DISABLE_HOST_CHECK':
400 $xcmd = $cmd{0} === 'D' ? 'DISABLE' : 'ENABLE';
401 $xcmd .= '_HOST_SVC_CHECKS';
402 if (!empty($param['_services-too']))
403 $nagios_commands = $this->_build_command($xcmd, $param);
404 break;
406 case 'ENABLE_HOST_SVC_NOTIFICATIONS':
407 case 'DISABLE_HOST_SVC_NOTIFICATIONS':
408 $xcmd = $cmd{0} === 'D' ? 'DISABLE' : 'ENABLE';
409 $xcmd .= '_HOST_NOTIFICATIONS';
410 if (!empty($param['_host-too']))
411 $nagios_commands = $this->_build_command($xcmd, $param);
412 break;
413 case 'ENABLE_HOSTGROUP_SVC_CHECKS':
414 case 'DISABLE_HOSTGROUP_SVC_CHECKS':
415 case 'ENABLE_SERVICEGROUP_SVC_CHECKS':
416 case 'DISABLE_SERVICEGROUP_SVC_CHECKS':
417 case 'ENABLE_HOSTGROUP_SVC_NOTIFICATIONS':
418 case 'DISABLE_HOSTGROUP_SVC_NOTIFICATIONS':
419 case 'ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS':
420 case 'DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS':
421 case 'SCHEDULE_HOSTGROUP_SVC_DOWNTIME':
422 case 'SCHEDULE_SERVICEGROUP_SVC_DOWNTIME':
423 if(strpos($cmd, 'DOWNTIME') && isset($param['fixed']) && $param['fixed']) {
424 $grouptype = strtolower(substr($cmd, 9, strpos($cmd, '_', 10) - 9));
425 $this->schedule_retrospectively($grouptype, 'service', $param[$grouptype.'_name'], $param['start_time'], $param['end_time'], $param['comment']);
426 if (!empty($param['_host-too']))
427 $this->schedule_retrospectively($grouptype, 'host', $param[$grouptype.'_name'], $param['start_time'], $param['end_time'], $param['comment']);
429 if (!empty($param['_host-too'])) {
430 unset($param['_host-too']);
431 $xcmd = str_replace('SVC', 'HOST', $cmd);
432 $nagios_commands = $this->_build_command($xcmd, $param);
434 break;
435 case 'SCHEDULE_SVC_DOWNTIME':
436 if(isset($param['fixed']) && $param['fixed']) {
437 $this->schedule_retrospectively('service', 'service', $param['service'], $param['start_time'], $param['end_time'], $param['comment']);
439 $date_validation_result = $this->_validate_dates($param['start_time'], $param['end_time']);
440 if($date_validation_result !== true) {
441 $this->template->content->result = false;
442 $this->template->content->error = $date_validation_result;
443 return;
445 break;
446 case 'ACKNOWLEDGE_HOST_PROBLEM':
447 case 'REMOVE_HOST_ACKNOWLEDGEMENT':
448 if (!empty($param['_services-too'])) {
449 unset($param['_services-too']);
450 $xcmd = str_replace('HOST', 'SVC', $cmd);
451 $ls = Livestatus::instance();
452 $host_names = $param['host_name'];
453 if (!is_array($host_names))
454 $host_names = array($host_names);
455 $xparam = $param;
456 unset($xparam['host_name']);
457 foreach ($host_names as $host_name) {
458 $services = $ls->getServices(array('filter' => array('host_name' => $host_name), 'columns' => array('description')));
459 if($services) {
460 foreach($services as $service) {
461 $xparam['service'] = $host_name.';'.$service['description'];
462 $nagios_commands = $this->_build_command($xcmd, $xparam, $nagios_commands);
467 break;
468 case 'SCHEDULE_SERVICEGROUP_HOST_DOWNTIME':
469 if(isset($param['fixed']) && $param['fixed']) {
470 $this->schedule_retrospectively('servicegroup', 'host', $param['servicegroup_name'], $param['start_time'], $param['end_time'], $param['comment']);
472 break;
473 case 'NACOMA_DEL_HOST':
474 case 'NACOMA_DEL_SERVICE':
475 // Delete the host/service then route to NACOMA SAVE_CONFIG page
476 $res = true;
477 if (isset($param['service'])) {
478 foreach ($param['service'] as $service) {
479 $res &= nacoma::delService($service);
483 if (isset($param['host_name'])) {
484 foreach ($param['host_name'] as $host) {
485 $res &= nacoma::delHost($host);
489 if ($res)
490 return url::redirect('/configuration/configure?page=export.php');
491 break;
494 $nagios_commands = $this->_build_command($cmd, $param, $nagios_commands);
496 if (empty($nagios_commands))
497 $this->template->content->result = false;
499 $this->template->content->result = true;
500 while ($ncmd = array_pop($nagios_commands)) {
501 if(!nagioscmd::submit_to_nagios($ncmd)) {
502 $this->template->content->result = false;
503 // don't try to submit more commands
504 return;
510 * Display "You're not authorized" message
512 public function unauthorized($state=false)
514 $this->template->content = $this->add_view('command/unauthorized');
515 $this->template->content->error_message = _('You are not authorized to submit the specified command.');
516 switch ($state) {
517 case -1: # No command passed
518 $this->template->content->error_message = _('No command specified.');
519 $this->template->content->error_description = _('Please enter a valid '.
520 'command or use the available links in the GUI.');
521 break;
522 case -2: # Contact can't submit commands
523 $this->template->content->error_description = _("Your contact doesn't seem to configured ".
524 "to allow you to submit commands (i.e 'can_submit_commands' is not enabled). Please contact an administrator ".
525 "to enable this for you. ");
526 break;
527 case -3: # not authorized from cgi.cfg, and not a configured contact
528 $this->template->content->error_description = _("Your account doesn't have a " .
529 "configured contact, nor does it have permissions to submit commands to all " .
530 "objects. Please contact an administrator for assistance.");
531 break;
532 case -4:
533 $this->template->content->error_description = _("Your account isn't authorized " .
534 "to submit commands for this object type. Please contact an administrator for assistance.");
535 break;
536 case -5:
537 $this->template->content->error_description = _("Your account isn't authorized " .
538 "to submit commands for this object. Please contact an administrator for assistance.");
539 break;
541 default: # fallthrough, not authorized for anything
542 $this->template->content->error_description = _('Read the section of the '.
543 'documentation that deals with authentication and authorization in the CGIs for more information.');
546 $this->template->content->return_link_lable = _('Return from where you came');
550 * Translated helptexts for this controller
552 public static function _helptexts($id)
554 # No helptexts defined yet - this is just an example
555 # Tag unfinished helptexts with @@@HELPTEXT:<key> to make it
556 # easier to find those later
557 $helptexts = array(
558 'downtime_id' =>
559 _ ("The downtime you want to delete/cancel"),
560 'triggered_by' =>
561 _ ("With triggered downtime the start of the downtime ".
562 "is triggered by the start of some other scheduled " .
563 "host or service downtime"),
564 'duration' =>
565 _("Duration is given as a decimal value of full hours. " .
566 "Thus, 1h 15m should be written as <b>1.25</b>"),
568 if (array_key_exists($id, $helptexts)) {
569 echo $helptexts[$id];
571 else
572 echo sprintf(_("This helptext ('%s') is not translated yet"), $id);
576 * Handle submitting of one command for multiple objects
578 public function multi_action()
580 if (!isset($_REQUEST['multi_action'])) {
581 $this->template->content = $this->add_view('error');
582 $this->template->content->error_message = '<br /> &nbsp;'._('ERROR: Missing action parameter - unable to process request');
583 return false;
585 if (!isset($_REQUEST['object_select'])) {
586 $this->template->content = $this->add_view('error');
587 $this->template->content->error_message = '<br /> &nbsp;'._('ERROR: Missing objects - unable to process request');
588 return false;
590 if (!isset($_REQUEST['obj_type'])) {
591 $this->template->content = $this->add_view('error');
592 $this->template->content->error_message = '<br /> &nbsp;'._('ERROR: Missing object type - unable to process request');
593 return false;
596 $cmd_typ = $_REQUEST['multi_action'];
597 $obj_type = $_REQUEST['obj_type'];
598 $objects = $_REQUEST['object_select'];
600 $param_name = false;
601 switch ($obj_type) {
602 case 'hosts':
603 $param_name = 'host_name';
604 break;
605 case 'services':
606 $param_name = 'service';
607 break;
608 case 'hostgroups':
609 $param_name = 'hostgroup_name';
610 break;
611 case 'servicegroups':
612 $param_name = 'servicegroup_name';
613 break;
614 case 'comments':
615 $param_name = 'comment_id';
616 break;
617 case 'downtimes':
618 $param_name = 'downtime_id';
619 break;
622 $params = false;
624 foreach ($objects as $obj) {
625 $params[$param_name][] = $obj;
628 if (!empty($params) && !empty($cmd_typ)) {
629 $params['cmd_typ'] = $cmd_typ;
630 return $this->submit($cmd_typ, $params);
633 $this->template->content = $this->add_view('error');
634 $this->template->content->error_message = '<br /> &nbsp;'._('ERROR: Missing parameters - unable to process request');
635 return false;
639 * Wrapper around nagioscmd::build_command() to be able
640 * to create valid commands for multiple objects at once
642 public function _build_command($cmd = false, $param = false, $nagios_commands = false)
644 if (
645 (isset($param['host_name']) && is_array($param['host_name'])) ||
646 (isset($param['service']) && is_array($param['service'])) )
647 { # we have a multi command, i.e one command for multiple objects
649 # remove host_name (or service) from param
650 if (isset($param['host_name'])) {
651 $obj_list = $param['host_name'];
652 unset($param['host_name']);
653 $param_str = 'host_name';
654 } else {
655 $obj_list = $param['service'];
656 unset($param['service']);
657 $param_str = 'service';
660 # create new param array for each object
661 foreach ($obj_list as $obj) {
662 $multi_param = false;
663 $multi_param = $param;
664 $multi_param[$param_str] = $obj;
665 $nagios_commands[] = nagioscmd::build_command($cmd, $multi_param);
667 } else if ((isset($param['downtime_id']) && is_array($param['downtime_id'])) ||
668 (isset($param['trigger_id']) && is_array($param['trigger_id'])) ||
669 (isset($param['comment_id']) && is_array($param['comment_id']))) {
670 if (isset($param['trigger_id']))
671 $param_str = 'trigger_id';
672 elseif (isset($param['downtime_id']))
673 $param_str = 'downtime_id';
674 else
675 $param_str = 'comment_id';
676 foreach ($param[$param_str] as $did) {
677 $parts = explode(';',$did,2);
678 $replace_to_service = false;
679 if( count($parts) == 2 ) {
680 $did = $parts[0];
681 $replace_to_service = $parts[1] != 0;
683 $multi_param = $param;
684 $multi_param[$param_str] = $did;
686 $this_cmd = nagioscmd::cmd_info($cmd); /* Needs to be extraced so _HOST_ can be replaced to _SVC_ */
687 if( $replace_to_service )
688 $this_cmd['template'] = str_replace('_HOST_','_SVC_',$this_cmd['template']);
689 $nagios_commands[] = nagioscmd::build_command($this_cmd, $multi_param);
691 } else {
692 $nagios_commands[] = nagioscmd::build_command($cmd, $param);
695 return $nagios_commands;
699 * Executes custom commands and return output to ajax call.
700 * @param $command_name string
701 * @param $type string
702 * @param $host string
703 * @param $service string
704 * @return string
706 public function exec_custom_command($command_name, $type=false, $host=false, $service=false)
708 // Stop redirects
709 $this->auto_render=false;
710 if ($host === false) {
711 echo "No object type or identifier were set. Aborting.";
712 return;
714 // Get object data.
715 $ls = Livestatus::instance();
716 if(!empty($host) && empty($service)) {
717 $result_data = $ls->getHosts(array('filter' => array('name' => $host)));
719 else if(!empty($host) && !empty($service)) {
720 $result_data = $ls->getServices(array('filter' => array('host_name' => $host, 'description' => $service)));
722 $obj = (object)$result_data[0];
724 $custom_variables = array_combine($obj->custom_variable_names, $obj->custom_variable_values);
725 $custom_commands = Custom_command_Model::parse_custom_variables($custom_variables, $command_name);
726 if (empty($custom_commands)) {
727 echo "You are not authorized to run this command or it doesn't exist.";
728 return;
729 } else {
730 $command = $custom_commands[$command_name];
731 $command = nagstat::process_macros($command, $obj, $type);
732 // Set host/service comment that the command has been run
733 switch($type) {
734 case 'host':
735 $comment = "ADD_HOST_COMMENT;".$host.";1;".Auth::instance()->get_user()->username.";Executed custom command: ".ucwords(strtolower(str_replace('_', ' ', $command_name)));
736 break;
737 case 'service':
738 $comment = "ADD_SVC_COMMENT;".$host.";".$service.";1;".Auth::instance()->get_user()->username.";Executed custom command: ".ucwords(strtolower(str_replace('_', ' ', $command_name)));
739 break;
741 // Submit logs to nagios as comments.
742 $nagios_base_path = Kohana::config('config.nagios_base_path');
743 nagioscmd::submit_to_nagios($comment);
744 exec($command, $output, $status);
746 if ($status === 0) {
747 if (is_array($output)) {
748 $output = implode('<br />', $output);
750 echo $output;
751 } else {
752 echo "Script failed with status: " . $status;
753 return;