summaryrefslogtreecommitdiffstats
path: root/modules-available/rebootcontrol/page.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/rebootcontrol/page.inc.php')
-rw-r--r--modules-available/rebootcontrol/page.inc.php241
1 files changed, 115 insertions, 126 deletions
diff --git a/modules-available/rebootcontrol/page.inc.php b/modules-available/rebootcontrol/page.inc.php
index 3a438504..80eff842 100644
--- a/modules-available/rebootcontrol/page.inc.php
+++ b/modules-available/rebootcontrol/page.inc.php
@@ -3,7 +3,10 @@
class Page_RebootControl extends Page
{
- private $action = false;
+ /**
+ * @var bool whether we have a SubPage from the pages/ subdir
+ */
+ private $haveSubpage = false;
/**
* Called before any page rendering happens - early hook to check parameters etc.
@@ -17,62 +20,87 @@ class Page_RebootControl extends Page
Util::redirect('?do=Main'); // does not return
}
- $this->action = Request::any('action', 'show', 'string');
-
-
- if ($this->action === 'reboot' || $this->action === 'shutdown') {
-
- $requestedClients = Request::post('clients', false, 'array');
- if (!is_array($requestedClients) || empty($requestedClients)) {
- Message::addError('no-clients-selected');
- Util::redirect();
- }
+ if (User::hasPermission('jumphost.*')) {
+ Dashboard::addSubmenu('?do=rebootcontrol&show=jumphost', Dictionary::translate('jumphosts'));
+ }
+ if (User::hasPermission('subnet.*')) {
+ Dashboard::addSubmenu('?do=rebootcontrol&show=subnet', Dictionary::translate('subnets'));
+ }
- $actualClients = RebootQueries::getMachinesByUuid($requestedClients);
- if (count($actualClients) !== count($requestedClients)) {
- // We could go ahead an see which ones were not found in DB but this should not happen anyways unless the
- // user manipulated the request
- Message::addWarning('some-machine-not-found');
+ $section = Request::any('show', false, 'string');
+ if ($section !== false) {
+ $section = preg_replace('/[^a-z]/', '', $section);
+ if (file_exists('modules/rebootcontrol/pages/' . $section . '.inc.php')) {
+ require_once 'modules/rebootcontrol/pages/' . $section . '.inc.php';
+ $this->haveSubpage = true;
+ SubPage::doPreprocess();
+ } else {
+ Message::addError('main.invalid-action', $section);
+ return;
}
- // Filter ones with no permission
- foreach (array_keys($actualClients) as $idx) {
- if (!User::hasPermission('action.' . $this->action, $actualClients[$idx]['locationid'])) {
- Message::addWarning('locations.no-permission-location', $actualClients[$idx]['locationid']);
- unset($actualClients[$idx]);
+ } else {
+ $action = Request::post('action', 'show', 'string');
+
+ if ($action === 'reboot' || $action === 'shutdown') {
+ $this->execRebootShutdown($action);
+ } elseif ($action === 'toggle-wol') {
+ User::assertPermission('woldiscover');
+ $enabled = Request::post('enabled', false);
+ $c2c = Request::post('enabled-c2c', false);
+ $port = Request::post('port', 9, 'int');
+ $dbcast = Request::post('dbcast', '', 'string');
+ Property::set(RebootControl::KEY_AUTOSCAN_DISABLED, !$enabled);
+ Property::set(RebootControl::KEY_SCAN_CLIENT_TO_CLIENT, $c2c);
+ Property::set(RebootControl::KEY_UDP_PORT, $port);
+ Property::set(RebootControl::KEY_BROADCAST_ADDRESS, $dbcast);
+ if ($enabled) {
+ Message::addInfo('woldiscover-enabled');
} else {
- $locationId = $actualClients[$idx]['locationid'];
+ Message::addInfo('woldiscover-disabled');
}
+ $section = 'subnet'; // For redirect below
}
- // See if anything is left
- if (!is_array($actualClients) || empty($actualClients)) {
- Message::addError('no-clients-selected');
- Util::redirect();
- }
- usort($actualClients, function($a, $b) {
- $a = ($a['state'] === 'IDLE' || $a['state'] === 'OCCUPIED');
- $b = ($b['state'] === 'IDLE' || $b['state'] === 'OCCUPIED');
- if ($a === $b)
- return 0;
- return $a ? -1 : 1;
- });
- if ($this->action === 'shutdown') {
- $mode = 'SHUTDOWN';
- $minutes = Request::post('s-minutes', 0, 'int');
- } elseif (Request::any('quick', false, 'string') === 'on') {
- $mode = 'KEXEC_REBOOT';
- $minutes = Request::post('r-minutes', 0, 'int');
- } else {
- $mode = 'REBOOT';
- $minutes = Request::post('r-minutes', 0, 'int');
- }
- $task = RebootControl::execute($actualClients, $mode, $minutes, $locationId);
- if (Taskmanager::isTask($task)) {
- Util::redirect("?do=rebootcontrol&taskid=" . $task["id"]);
+ }
+
+ if (Request::isPost()) {
+ Util::redirect('?do=rebootcontrol' . ($section ? '&show=' . $section : ''));
+ } elseif ($section === false) {
+ if (User::hasPermission('action.*')) {
+ Util::redirect('?do=rebootcontrol&show=task');
+ } elseif (User::hasPermission('jumphost.*')) {
+ Util::redirect('?do=rebootcontrol&show=jumphost');
} else {
- Util::redirect("?do=rebootcontrol");
+ Util::redirect('?do=rebootcontrol&show=subnet');
}
}
+ }
+ private function execRebootShutdown($action)
+ {
+ $requestedClients = Request::post('clients', false, 'array');
+ if (!is_array($requestedClients) || empty($requestedClients)) {
+ Message::addError('no-clients-selected');
+ return;
+ }
+
+ $actualClients = RebootUtils::getFilteredMachineList($requestedClients, 'action.' . $action);
+ if ($actualClients === false)
+ return;
+ RebootUtils::sortRunningFirst($actualClients);
+ if ($action === 'shutdown') {
+ $mode = 'SHUTDOWN';
+ $minutes = Request::post('s-minutes', 0, 'int');
+ } elseif (Request::any('quick', false, 'string') === 'on') {
+ $mode = 'KEXEC_REBOOT';
+ $minutes = Request::post('r-minutes', 0, 'int');
+ } else {
+ $mode = 'REBOOT';
+ $minutes = Request::post('r-minutes', 0, 'int');
+ }
+ $task = RebootControl::execute($actualClients, $mode, $minutes);
+ if (Taskmanager::isTask($task)) {
+ Util::redirect("?do=rebootcontrol&show=task&what=task&taskid=" . $task["id"]);
+ }
}
/**
@@ -81,94 +109,55 @@ class Page_RebootControl extends Page
protected function doRender()
{
- if ($this->action === 'show') {
-
- $data = [];
- $task = Request::get("taskid", false, 'string');
- if ($task !== false) {
- $task = Taskmanager::status($task);
- }
-
- if (Taskmanager::isTask($task)) {
-
- $data['taskId'] = $task['id'];
- $data['locationId'] = $task['data']['locationId'];
- $data['locationName'] = Location::getName($task['data']['locationId']);
- $uuids = array_map(function($entry) {
- return $entry['machineuuid'];
- }, $task['data']['clients']);
- $data['clients'] = RebootQueries::getMachinesByUuid($uuids);
- Render::addTemplate('status', $data);
-
- } else {
-
- //location you want to see, default are "not assigned" clients
- $requestedLocation = Request::get('location', false, 'int');
- $allowedLocs = User::getAllowedLocations("action.*");
- if (empty($allowedLocs)) {
- User::assertPermission('action.*');
- }
-
- if ($requestedLocation === false) {
- if (in_array(0, $allowedLocs)) {
- $requestedLocation = 0;
- } else {
- $requestedLocation = reset($allowedLocs);
- }
- }
-
- $data['locations'] = Location::getLocations($requestedLocation, 0, true);
-
- // disable each location user has no permission for
- foreach ($data['locations'] as &$loc) {
- if (!in_array($loc["locationid"], $allowedLocs)) {
- $loc["disabled"] = "disabled";
- } elseif ($loc["locationid"] == $requestedLocation) {
- $data['location'] = $loc['locationname'];
- }
- }
- // Always show public key (it's public, isn't it?)
- $data['pubKey'] = SSHKey::getPublicKey();
-
- // Only enable shutdown/reboot-button if user has permission for the location
- Permission::addGlobalTags($data['perms'], $requestedLocation, ['newkeypair', 'action.shutdown', 'action.reboot']);
-
- Render::addTemplate('header', $data);
-
- // only fill table if user has at least one permission for the location
- if (!in_array($requestedLocation, $allowedLocs)) {
- Message::addError('locations.no-permission-location', $requestedLocation);
- } else {
- $data['data'] = RebootQueries::getMachineTable($requestedLocation);
- Render::addTemplate('_page', $data);
- }
-
- // Append list of active reboot/shutdown tasks
- $active = RebootControl::getActiveTasks($allowedLocs);
- if (!empty($active)) {
- foreach ($active as &$entry) {
- $entry['locationName'] = Location::getName($entry['locationId']);
- }
- unset($entry);
- Render::addTemplate('task-list', ['list' => $active]);
- }
-
- }
+ $port = (int)Property::get(RebootControl::KEY_UDP_PORT);
+ if ($port < 1 || $port > 65535) {
+ $port = 9;
+ }
+ // Always show public key (it's public, isn't it?)
+ $data = [
+ 'pubkey' => SSHKey::getPublicKey(),
+ 'wol_auto_checked' => Property::get(RebootControl::KEY_AUTOSCAN_DISABLED) ? '' : 'checked',
+ 'wol_c2c_checked' => Property::get(RebootControl::KEY_SCAN_CLIENT_TO_CLIENT) ? 'checked' : '',
+ 'port' => $port,
+ 'dbcast' => Property::get(RebootControl::KEY_BROADCAST_ADDRESS),
+ ];
+ Permission::addGlobalTags($data['perms'], null, ['newkeypair', 'woldiscover']);
+ Render::addTemplate('header', $data);
+
+ if ($this->haveSubpage) {
+ SubPage::doRender();
}
}
- function doAjax()
+ protected function doAjax()
{
- $this->action = Request::post('action', false, 'string');
- if ($this->action === 'generateNewKeypair') {
+ $action = Request::post('action', false, 'string');
+ if ($action === 'generateNewKeypair') {
User::assertPermission("newkeypair");
Property::set("rebootcontrol-private-key", false);
echo SSHKey::getPublicKey();
+ } elseif ($action === 'clientstatus') {
+ $clients = Request::post('clients');
+ if (is_array($clients)) {
+ // XXX No permission check here, should we consider this as leaking sensitive information?
+ $machines = RebootUtils::getMachinesByUuid(array_values($clients), false, ['machineuuid', 'state']);
+ $ret = [];
+ foreach ($machines as $machine) {
+ switch ($machine['state']) {
+ case 'OFFLINE': $val = 'glyphicon-off'; break;
+ case 'IDLE': $val = 'glyphicon-ok green'; break;
+ case 'OCCUPIED': $val = 'glyphicon-user red'; break;
+ case 'STANDBY': $val = 'glyphicon-off green'; break;
+ default: $val = 'glyphicon-question-sign'; break;
+ }
+ $ret[$machine['machineuuid']] = $val;
+ }
+ Header('Content-Type: application/json; charset=utf-8');
+ echo json_encode($ret);
+ }
} else {
echo 'Invalid action.';
}
}
-
-
}