%PDF- %PDF-
Direktori : /backups/router/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/ |
Current File : //backups/router/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/SystemController.php |
<?php /** * Copyright (C) 2019-2024 Deciso B.V. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ namespace OPNsense\Core\Api; use OPNsense\Base\ApiControllerBase; use OPNsense\Core\ACL; use OPNsense\Core\Backend; use OPNsense\Core\Config; use OPNsense\System\SystemStatus; use OPNsense\System\SystemStatusCode; /** * Class SystemController * @package OPNsense\Core */ class SystemController extends ApiControllerBase { public function haltAction() { if ($this->request->isPost()) { (new Backend())->configdRun('system halt', true); return ['status' => 'ok']; } else { return ['status' => 'failed']; } } public function rebootAction() { if ($this->request->isPost()) { (new Backend())->configdRun('system reboot', true); return ['status' => 'ok']; } else { return ['status' => 'failed']; } } public function statusAction() { $response['metadata'] = [ /* 'system' represents the status of the top notification after sorting */ 'system' => [ 'status' => SystemStatusCode::OK->value, 'message' => gettext('No pending messages'), 'title' => gettext('System'), ], 'translations' => [ 'dialogTitle' => gettext('System Status'), 'dialogCloseButton' => gettext('Close') ], 'subsystems' => [] ]; $backend = new Backend(); $statuses = json_decode(trim($backend->configdpRun('system status', [$this->request->get('path')])), true); if ($statuses) { $order = SystemStatusCode::toValueNameArray(); $acl = new ACL(); foreach ($statuses as $subsystem => $status) { unset($statuses[$subsystem]['scope']); $statuses[$subsystem]['status'] = $order[$status['statusCode']]; if (!empty($status['location'])) { if (!$acl->isPageAccessible($this->getUserName(), $status['location'])) { unset($statuses[$subsystem]); continue; } } } /* Sort on the highest notification (not banner) error level after the ACL check */ $filteredStatuses = array_filter($statuses, function ($item) { return !$item['isBanner']; }); $statusCodes = array_column($filteredStatuses, 'statusCode'); sort($statusCodes); $response['metadata']['system']['status'] = $order[$statusCodes[0] ?? 2]; // sort on status code and priority where priority is the tie breaker uasort($statuses, function ($a, $b) { if ($a['statusCode'] === $b['statusCode']) { return $a['priority'] <=> $b['priority']; } return $a['statusCode'] <=> $b['statusCode']; }); foreach ($statuses as &$status) { if (!empty($status['timestamp'])) { $age = time() - $status['timestamp']; if ($age < 0) { /* time jump, do nothing */ } elseif ($age < 60) { if ($age == 1) { $status['age'] = sprintf(gettext('%s second ago'), $age); } else { $status['age'] = sprintf(gettext('%s seconds ago'), $age); } } elseif ($age < 60 * 60) { $age = intdiv($age, 60); if ($age == 1) { $status['age'] = sprintf(gettext('%s minute ago'), $age); } else { $status['age'] = sprintf(gettext('%s minutes ago'), $age); } } elseif ($age < 60 * 60 * 24) { $age = intdiv($age, 60 * 60); if ($age == 1) { $status['age'] = sprintf(gettext('%s hour ago'), $age); } else { $status['age'] = sprintf(gettext('%s hours ago'), $age); } } elseif ($age < 60 * 60 * 24 * 7) { $age = intdiv($age, 60 * 60 * 24); if ($age == 1) { $status['age'] = sprintf(gettext('%s day ago'), $age); } else { $status['age'] = sprintf(gettext('%s days ago'), $age); } } elseif ($age < 60 * 60 * 24 * 30) { $age = intdiv($age, 60 * 60 * 24 * 7); if ($age == 1) { $status['age'] = sprintf(gettext('%s week ago'), $age); } else { $status['age'] = sprintf(gettext('%s weeks ago'), $age); } } elseif ($age < 60 * 60 * 24 * 365) { $age = intdiv($age, 60 * 60 * 24 * 30); if ($age == 1) { $status['age'] = sprintf(gettext('%s month ago'), $age); } else { $status['age'] = sprintf(gettext('%s months ago'), $age); } } else { $age = intdiv($age, 60 * 60 * 24 * 365); if ($age == 1) { $status['age'] = sprintf(gettext('%s year ago'), $age); } else { $status['age'] = sprintf(gettext('%s years ago'), $age); } } } } $response['subsystems'] = $statuses; unset($response['status']); } return $response; } public function dismissStatusAction() { if ($this->request->isPost() && $this->request->hasPost("subject")) { $acl = new ACL(); $backend = new Backend(); $subsystem = $this->request->getPost("subject"); $system = json_decode(trim($backend->configdRun('system status')), true); if (array_key_exists($subsystem, $system)) { if (!empty($system[$subsystem]['location'])) { $aclCheck = $system[$subsystem]['location']; if ( $acl->isPageAccessible($this->getUserName(), $aclCheck) || !$acl->hasPrivilege($this->getUserName(), 'user-config-readonly') ) { $status = trim($backend->configdRun(sprintf('system dismiss status %s', $subsystem))); if ($status == "OK") { return [ "status" => "ok" ]; } } } } } return ["status" => "failed"]; } }