diff options
Diffstat (limited to 'modules-available/dnbd3/page.inc.php')
-rw-r--r-- | modules-available/dnbd3/page.inc.php | 178 |
1 files changed, 142 insertions, 36 deletions
diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php index 1fa38805..d8dd6cb8 100644 --- a/modules-available/dnbd3/page.inc.php +++ b/modules-available/dnbd3/page.inc.php @@ -11,8 +11,10 @@ class Page_Dnbd3 extends Page Message::addError('main.no-permission'); Util::redirect('?do=Main'); } + $action = Request::post('action', false, 'string'); if ($action === 'refresh') { + User::assertPermission('refresh'); Dnbd3Util::updateServerStatus(); } elseif ($action === 'delserver') { $this->deleteServer(); @@ -37,6 +39,7 @@ class Page_Dnbd3 extends Page Message::addError('not-automatic-server', $server['ip']); return; } + $this->assertPermission($server); $bgr = Request::post('bgr', false, 'bool'); $firewall = Request::post('firewall', false, 'bool'); $overrideIp = false; @@ -73,6 +76,7 @@ class Page_Dnbd3 extends Page private function toggleUsage() { + User::assertPermission('toggle-usage'); $enabled = Request::post('enabled', false, 'bool'); $nfs = Request::post('with-nfs', false, 'bool'); $task = Dnbd3::setEnabled($enabled); @@ -83,6 +87,7 @@ class Page_Dnbd3 extends Page private function saveServerLocations() { $server = $this->getServerById(); + $this->assertPermission($server); $locids = Request::post('location', [], 'array'); if (empty($locids)) { Database::exec('DELETE FROM dnbd3_server_x_location WHERE serverid = :serverid', @@ -99,6 +104,7 @@ class Page_Dnbd3 extends Page private function addServer() { + User::assertPermission('configure.external'); $ip = Request::post('newip', false, 'string'); if ($ip === false) { Message::addError('main.parameter-missing', 'ip'); @@ -126,6 +132,7 @@ class Page_Dnbd3 extends Page private function deleteServer() { $server = $this->getServerById(); + $this->assertPermission($server); if ($server['fixedip'] === '<self>') return; if (!is_null($server['machineuuid'])) { @@ -156,9 +163,10 @@ class Page_Dnbd3 extends Page private function showServerList() { + User::assertPermission('access-page'); $dynClients = RunMode::getForMode(Page::getModule(), 'proxy', true, true); $res = Database::simpleQuery('SELECT s.serverid, s.machineuuid, s.fixedip, s.lastseen AS dnbd3lastseen, - s.uptime, s.totalup, s.totaldown, s.clientcount, s.disktotal, s.diskfree, Count(sxl.locationid) AS locations, + s.uptime, s.totalup, s.totaldown, s.clientcount, s.disktotal, s.diskfree, GROUP_CONCAT(sxl.locationid) AS locations, s.errormsg FROM dnbd3_server s LEFT JOIN dnbd3_server_x_location sxl USING (serverid) @@ -166,8 +174,22 @@ class Page_Dnbd3 extends Page $servers = array(); $sort = array(); $NOW = time(); + $externalAllowed = User::hasPermission('configure.external'); + $locsRunmode = User::getAllowedLocations('configure.proxy'); while ($server = $res->fetch(PDO::FETCH_ASSOC)) { - if (isset($dynClients[$server['machineuuid']])) { + if (!is_null($server['machineuuid'])) { + // Auto proxy + if (!isset($dynClients[$server['machineuuid']])) { + // Not in runmode dnbd3!? + if ($NOW - $server['dnbd3lastseen'] > 660) { + // Also seems to be down - delete + Database::exec('DELETE FROM dnbd3_server WHERE serverid = :serverid', + array('serverid' => $server['serverid'])); + continue; + } + // Not in runmode but (still?) up -- show + $server += ['locationid' => null, 'hostname' => '<invalid>']; + } $server += $dynClients[$server['machineuuid']]; unset($dynClients[$server['machineuuid']]); } @@ -195,6 +217,23 @@ class Page_Dnbd3 extends Page $server['slxOk'] = true; } } + if (is_null($server['locations'])) { + $server['locations'] = 0; + } else { + $locations = explode(',', $server['locations']); + $server['locations'] = count($locations); + } + // Permission to edit + if (is_null($server['machineuuid'])) { + if (!$externalAllowed) { + $server['edit_disabled'] = 'disabled'; + } + } else { + if (!array_key_exists('locationid', $server) || !in_array($server['locationid'], $locsRunmode)) { + $server['edit_disabled'] = 'disabled'; + } + } + // Array for sorting if ($server['self']) { $sort[] = '---'; } else { @@ -203,66 +242,99 @@ class Page_Dnbd3 extends Page $servers[] = $server; } foreach ($dynClients as $server) { + $server['edit_disabled'] = 'disabled'; $servers[] = $server; $sort[] = '-' . $server['machineuuid']; - Database::exec('INSERT INTO dnbd3_server (machineuuid) VALUES (:uuid)', array('uuid' => $server['machineuuid'])); + Database::exec('INSERT IGNORE INTO dnbd3_server (machineuuid) VALUES (:uuid)', array('uuid' => $server['machineuuid'])); } array_multisort($sort, SORT_ASC, $servers); - Render::addTemplate('page-serverlist', array( + $data = array( 'list' => $servers, 'enabled' => Dnbd3::isEnabled(), 'enabled_checked_s' => Dnbd3::isEnabled() ? 'checked' : '', 'nfs_checked_s' => Dnbd3::hasNfsFallback() ? 'checked' : '', 'rebootcontrol' => Module::isAvailable('rebootcontrol', false) - )); + ); + Permission::addGlobalTags($data['perms'], null, ['view.details', 'refresh', 'toggle-usage', 'configure.proxy', 'configure.external']); + Render::addTemplate('page-serverlist', $data); } private function showProxyDetails() { + User::assertPermission('view.details'); $server = $this->getServerById(); Render::addTemplate('page-proxy-header', $server); - $stats = Dnbd3Rpc::query($server['ip'], 5003,true, true, false, true); + $stats = Dnbd3Rpc::query($server['ip'], 5003, true, true, true, true, true, true); if (!is_array($stats) || !isset($stats['runId'])) { Message::addError('server-unreachable'); return; } - $stats['bytesSent_s'] = Util::readableFileSize($stats['bytesSent']); - $stats['bytesReceived_s'] = Util::readableFileSize($stats['bytesReceived']); + foreach (['bytesSent', 'bytesReceived', 'spaceTotal', 'spaceFree'] as $key) { + $stats[$key . '_s'] = Util::readableFileSize($stats[$key]); + } + if ($stats['spaceTotal'] > 0) { + $stats['percentFree'] = ($stats['spaceFree'] / $stats['spaceTotal']) * 100; + $stats['percentFree'] = round($stats['percentFree'], $stats['percentFree'] < 10 ? 1 : 0); + } $stats['uptime_s'] = floor($stats['uptime'] / 86400) . 'd ' . gmdate('H:i:s', $stats['uptime']); + $stats['tab_config'] = is_string($stats['config']); + $stats['tab_altservers'] = is_array($stats['altservers']); Render::addTemplate('page-proxy-stats', $stats); - // TODO $images = Dnbd3Rpc::query($server['ip'], 5003,false, false, true); - $confAlts = Dnbd3Rpc::query($server['ip'], 5003,false, false, false, false, true, true); + Render::openTag('div', ['class' => 'tab-content']); $ips = array(); $sort = array(); foreach ($stats['clients'] as &$c) { $c['bytesSent_s'] = Util::readableFileSize($c['bytesSent']); $sort[] = $c['bytesSent']; - $ips[] = preg_replace('/:\d+$/', '', $c['address']); + $ips[preg_replace('/:\d+$/', '', $c['address'])] = true; } + $ips = array_keys($ips); array_multisort($sort, SORT_DESC, $stats['clients']); - Render::openTag('div', ['class' => 'row']); // Config - if (is_string($confAlts['config'])) { - Render::addTemplate('page-proxy-config', $confAlts); + if (is_string($stats['config'])) { + preg_match_all('/^((?<sec>\[.*\])|(?<key>[^=]+)=(?<val>.*)|(?<other>[^\[][^=]*))$/m', $stats['config'], $out, PREG_SET_ORDER); + $stats['config'] = []; + foreach ($out as $line) { + if (!empty($line['sec'])) { + $stats['config'][] = ['class1' => 'text-primary', 'text1' => $line['sec']]; + } elseif (!empty($line['other'])) { + $stats['config'][] = ['class1' => 'text-muted', 'text1' => $line['other']]; + } else { + $extra = ''; + $class2 = 'slx-bold'; + if (in_array($line['key'], ['serverPenalty', 'clientPenalty'])) { + $extra = round($line['val'] / 1000, 1) . 'ms'; + } elseif (in_array($line['key'], ['uplinkTimeout', 'clientTimeout'])) { + $extra = round($line['val'] / 1000, 1) . 's'; + } elseif (in_array($line['key'], ['maxPayload', 'maxReplicationSize'])) { + $extra = Util::readableFilesize($line['val']); + } elseif ($line['val'] === 'true') { + $class2 .= ' text-success'; + } elseif ($line['val'] === 'false') { + $class2 .= ' text-danger'; + } + $stats['config'][] = ['text1' => $line['key'], 'class2' => $class2, 'text2' => $line['val'] . ' ', 'extra' => $extra]; + } + } + Render::addTemplate('page-proxy-config', $stats); } - if (is_array($confAlts['altservers'])) { - foreach ($confAlts['altservers'] as &$as) { + if (is_array($stats['altservers'])) { + foreach ($stats['altservers'] as &$as) { $as['rtt'] = round(array_sum($as['rtt']) / count($as['rtt']) / 1000, 2); } unset($as); - Render::addTemplate('page-proxy-altservers', $confAlts); + Render::addTemplate('page-proxy-altservers', $stats); } - Render::closeTag('div'); - Render::openTag('div', ['class' => 'row']); // Count locations - $res = Database::simpleQuery('SELECT locationid, Count(*) AS cnt FROM machine WHERE clientip IN (:ips) GROUP BY locationid', compact('ips')); + $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt FROM machine + WHERE clientip IN (:ips) AND state IN ('IDLE', 'OCCUPIED') GROUP BY locationid", compact('ips')); $locCount = Location::getLocationsAssoc(); $locCount[0] = array( 'locationname' => '/', 'depth' => 0, - 'recCount' => 0, ); foreach ($locCount as &$loc) { + $loc['clientCount'] = 0; $loc['recCount'] = 0; } $showLocs = false; @@ -281,18 +353,27 @@ class Page_Dnbd3 extends Page $locCount[$p]['recCount'] += $row['cnt']; } } + $locCount[0]['recCount'] += $row['cnt']; } if ($showLocs) { - $locCount = array_filter($locCount, function ($v) { return isset($v['keep']); }); - Render::addTemplate('page-proxy-loclist', array('list' => array_values($locCount))); + $stats['loclist'] = array_values(array_filter($locCount, function ($v) { return isset($v['keep']); })); } Render::addTemplate('page-proxy-clients', $stats); + $sort1 = $sort2 = []; + foreach ($stats['images'] as &$image) { + $image['size_s'] = Util::readableFileSize($image['size']); + $sort1[] = $image['users']; + $sort2[] = $image['name']; + } + array_multisort($sort1, SORT_NUMERIC | SORT_DESC, $sort2, SORT_ASC, $stats['images']); + Render::addTemplate('page-proxy-images', $stats); Render::closeTag('div'); } private function showServerLocationEdit() { $server = $this->getServerById(); + $this->assertPermission($server); // Get selected ones $res = Database::simpleQuery('SELECT locationid FROM dnbd3_server_x_location WHERE serverid = :serverid', array('serverid' => $server['serverid'])); @@ -328,14 +409,14 @@ class Page_Dnbd3 extends Page Message::addError('main.parameter-missing', 'server'); Util::redirect('?do=dnbd3'); } - $server = Database::queryFirst('SELECT s.serverid, s.machineuuid, s.fixedip, m.clientip, m.hostname + $server = Database::queryFirst('SELECT s.serverid, s.machineuuid, s.fixedip, m.clientip, m.hostname, m.locationid FROM dnbd3_server s LEFT JOIN machine m USING (machineuuid) WHERE s.serverid = :serverId', compact('serverId')); if ($server === false) { if (AJAX) die('Invalid server id'); - Message::addError('server-non-existent', 'server'); + Message::addError('server-non-existent', $serverId); Util::redirect('?do=dnbd3'); } if (!is_null($server['fixedip'])) { @@ -348,6 +429,15 @@ class Page_Dnbd3 extends Page return $server; } + private function assertPermission($server) + { + if (isset($server['machineuuid'])) { + User::assertPermission('configure.proxy', $server['locationid'], '?do=dnbd3'); + } else { + User::assertPermission('configure.external', null, '?do=dnbd3'); + } + } + /* * AJAX */ @@ -371,6 +461,7 @@ class Page_Dnbd3 extends Page private function ajaxServerTest() { + User::assertPermission('configure.external'); Header('Content-Type: application/json; charset=utf-8'); $ip = Request::post('ip', false, 'string'); if ($ip === false) @@ -407,6 +498,7 @@ class Page_Dnbd3 extends Page echo 'Not automatic server.'; return; } + $this->assertPermission($server); $rm = RunMode::getForMode(Page::getModule(), 'proxy', false, true); if (!isset($rm[$server['machineuuid']])) { echo 'Error: RunMode entry missing.'; @@ -423,23 +515,37 @@ class Page_Dnbd3 extends Page if (!isset($server['machineuuid'])) { die('Not automatic server.'); } - if (!Module::isAvailable('rebootcontrol')) { - die('No rebootcontrol'); - } $uuid = $server['machineuuid']; - $task = RebootControl::reboot([ $uuid ]); + $task = Request::any('taskid', false, 'string'); if ($task === false) { - die('Taskmanager unreachable'); + $this->assertPermission($server); + if (!Module::isAvailable('rebootcontrol')) { + die('No rebootcontrol'); + } + $task = RebootControl::reboot([$uuid]); + if ($task === false) { + die('Taskmanager unreachable'); + } } - $task = Taskmanager::waitComplete($task, 2000); - if (is_array($task) && isset($task['data']) && isset($task['data']['clientStatus']) && isset($task['data']['clientStatus'][$uuid])) { - $status = $task['data']['clientStatus'][$uuid]; + $task = Taskmanager::waitComplete($task, 1000); + if (is_array($task) && isset($task['data']['clientStatus'][$uuid])) { + $status = [ + 'rebootStatus' => $task['data']['clientStatus'][$uuid], + 'taskStatus' => $task['statusCode'], + 'taskId' => $task['id'], + ]; if (!empty($task['data']['error'])) { - $status .= "\n --- \n" . $task['data']['error']; + $status['error'] = $task['data']['error']; } - die($status); + } else { + $status = [ + 'rebootStatus' => 'FAILURE', + 'taskStatus' => 'FAILURE', + 'taskId' => $task['id'], + ]; } - die('Unknown :-('); + Header('Content-Type: application/json; charset=utf-8'); + die(json_encode($status)); } } |