1 <?php
defined('SYSPATH') OR die('No direct access allowed.');
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
15 class Command_Controller
extends Authenticated_Controller
17 private $command_id = false;
18 private $cmd_params = array();
19 private $csrf_token = false;
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;
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;
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);
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>";
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);
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);
71 * Request a command to be submitted
72 * This method prints input fields to be selected for the
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');
83 $cmd = $this->input
->get('cmd_typ');
86 if ($params === false) {
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'];
99 case 'DEL_HOST_COMMENT':
100 case 'DEL_SVC_COMMENT':
101 $param['comment_id']['type'] = 'immutable';
103 case 'SCHEDULE_HOST_CHECK':
104 case 'SCHEDULE_SVC_CHECK':
105 case 'SCHEDULE_HOST_SVC_CHECKS':
106 $param['_force'] = $this->cb(_('Force Check'), '_force');
109 case 'PROCESS_HOST_CHECK_RESULT':
110 case 'PROCESS_SERVICE_CHECK_RESULT':
111 $param['_perfdata'] = array
114 'name' => _('Performance data'));
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
123 ('none' => _('Do nothing'),
124 'triggered' => _('Schedule triggered downtime'),
125 'fixed' => _('Schedule fixed downtime')),
126 'default' => 'triggered',
127 'name' => _('Child Hosts'));
129 case 'SCHEDULE_HOSTGROUP_HOST_DOWNTIME':
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');
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');
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');
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');
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');
165 case 'ACKNOWLEDGE_HOST_PROBLEM':
166 $param['_services-too'] = $this->cb(_('Acknowledge any problems on services too'), '_services-too');
168 case 'REMOVE_HOST_ACKNOWLEDGEMENT':
169 $param['_services-too'] = $this->cb(_('Remove any acknowledgements on services too'), '_services-too');
171 case 'NACOMA_DEL_SERVICE':
173 foreach ($params['service'] as $service) {
174 if (($hg = nacoma
::getHostgroupForService($service)))
175 $res[$service] = $hg;
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>';
191 case 'NACOMA_DEL_HOST':
192 return $this->commit($cmd, $params);
197 $info['params'] = $param;
199 $this->template
->toolbar
= new Toolbar_Controller( _( "Command" ), _( "Submit" ) );
200 $this->template
->content
->info
= $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);
210 if ($start_time +
$this->grace_time_in_s
>= $now)
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);
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
286 public function commit($cmd = false, $param=false)
289 if(!isset($_REQUEST['cmd_typ']))
290 return $this->unauthorized();
291 $cmd = $_REQUEST['cmd_typ'];
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>'));
313 $fallthrough = false;
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"));
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']);
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;
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']);
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']);
360 $nagios_commands = array_merge($this->_build_command('SCHEDULE_HOST_SVC_DOWNTIME', $param), $nagios_commands);
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']);
371 case 'SEND_CUSTOM_HOST_NOTIFICATION':
372 case 'SEND_CUSTOM_SVC_NOTIFICATION':
374 if (isset($param['_broadcast'])) {
375 unset($param['_broadcast']);
378 if (isset($param['_force'])) {
379 unset($param['_force']);
382 if (isset($param['_increment'])) {
383 unset($param['_increment']);
387 $param['options'] = $options;
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);
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);
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);
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);
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;
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);
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')));
460 foreach($services as $service) {
461 $xparam['service'] = $host_name.';'.$service['description'];
462 $nagios_commands = $this->_build_command($xcmd, $xparam, $nagios_commands);
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']);
473 case 'NACOMA_DEL_HOST':
474 case 'NACOMA_DEL_SERVICE':
475 // Delete the host/service then route to NACOMA SAVE_CONFIG page
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);
490 return url
::redirect('/configuration/configure?page=export.php');
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
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.');
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.');
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. ");
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.");
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.");
537 $this->template
->content
->error_description
= _("Your account isn't authorized " .
538 "to submit commands for this object. Please contact an administrator for assistance.");
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
559 _ ("The downtime you want to delete/cancel"),
561 _ ("With triggered downtime the start of the downtime ".
562 "is triggered by the start of some other scheduled " .
563 "host or service downtime"),
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];
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 /> '._('ERROR: Missing action parameter - unable to process request');
585 if (!isset($_REQUEST['object_select'])) {
586 $this->template
->content
= $this->add_view('error');
587 $this->template
->content
->error_message
= '<br /> '._('ERROR: Missing objects - unable to process request');
590 if (!isset($_REQUEST['obj_type'])) {
591 $this->template
->content
= $this->add_view('error');
592 $this->template
->content
->error_message
= '<br /> '._('ERROR: Missing object type - unable to process request');
596 $cmd_typ = $_REQUEST['multi_action'];
597 $obj_type = $_REQUEST['obj_type'];
598 $objects = $_REQUEST['object_select'];
603 $param_name = 'host_name';
606 $param_name = 'service';
609 $param_name = 'hostgroup_name';
611 case 'servicegroups':
612 $param_name = 'servicegroup_name';
615 $param_name = 'comment_id';
618 $param_name = 'downtime_id';
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 /> '._('ERROR: Missing parameters - unable to process request');
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)
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';
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';
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 ) {
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);
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
706 public function exec_custom_command($command_name, $type=false, $host=false, $service=false)
709 $this->auto_render
=false;
710 if ($host === false) {
711 echo "No object type or identifier were set. Aborting.";
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.";
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
735 $comment = "ADD_HOST_COMMENT;".$host.";1;".Auth
::instance()->get_user()->username
.";Executed custom command: ".ucwords(strtolower(str_replace('_', ' ', $command_name)));
738 $comment = "ADD_SVC_COMMENT;".$host.";".$service.";1;".Auth
::instance()->get_user()->username
.";Executed custom command: ".ucwords(strtolower(str_replace('_', ' ', $command_name)));
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);
747 if (is_array($output)) {
748 $output = implode('<br />', $output);
752 echo "Script failed with status: " . $status;