From f46409bf74e42de6490a7d80f319c132c3d6a43c Mon Sep 17 00:00:00 2001 From: Jonathan Bauer Date: Tue, 5 Sep 2017 15:56:17 +0200 Subject: [locations] fix missing locationId on ip/uuid ... ... when the client's ip falls within a known range but its uuid has not been recorded yet and the client requests its config by uuid. --- modules-available/locations/inc/location.inc.php | 37 ++++++++++++------------ 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'modules-available') diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php index 8b2ef262..e3fd35b7 100644 --- a/modules-available/locations/inc/location.inc.php +++ b/modules-available/locations/inc/location.inc.php @@ -285,29 +285,28 @@ class Location { $locationId = false; $ipLoc = self::getFromIp($ip); - if ($ipLoc !== false && $uuid !== false) { - // Machine ip maps to a location, and we have a client supplied uuid - $uuidLoc = self::getFromMachineUuid($uuid); - if ($uuidLoc === $ipLoc) { - $locationId = $uuidLoc; - } else if ($uuidLoc !== false) { - // Validate that the location the IP maps to is in the chain we get using the - // location determined by the uuid - $uuidLocations = self::getLocationRootChain($uuidLoc); - $ipLocations = self::getLocationRootChain($ipLoc); - if (in_array($uuidLoc, $ipLocations) // UUID loc is further up, OK - || (in_array($ipLoc, $uuidLocations) && count($ipLocations) + 1 >= count($uuidLocations)) // UUID is max one level deeper than IP loc, accept as well - ) { - // Close enough, allow + if ($ipLoc !== false) { + // Set locationId to ipLoc for now, it will be overwritten later if another case applies. + $locationId = $ipLoc; + if ($uuid !== false) { + // Machine ip maps to a location, and we have a client supplied uuid (which might not be known if the client boots for the first time) + $uuidLoc = self::getFromMachineUuid($uuid); + if ($uuidLoc === $ipLoc) { $locationId = $uuidLoc; - } else { + } else if ($uuidLoc !== false) { + // Validate that the location the IP maps to is in the chain we get using the + // location determined by the uuid + $uuidLocations = self::getLocationRootChain($uuidLoc); + $ipLocations = self::getLocationRootChain($ipLoc); + if (in_array($uuidLoc, $ipLocations) // UUID loc is further up, OK + || (in_array($ipLoc, $uuidLocations) && count($ipLocations) + 1 >= count($uuidLocations)) // UUID is max one level deeper than IP loc, accept as well + ) { + // Close enough, allow + $locationId = $uuidLoc; + } // UUID and IP disagree too much, play safe and ignore the UUID - $locationId = $ipLoc; } } - } else if ($ipLoc !== false) { - // No uuid, but ip maps to location; use that - $locationId = $ipLoc; } return $locationId; } -- cgit v1.2.3-55-g7522 From db82c6326bcbf09bcb8f938728394bf39d4681a3 Mon Sep 17 00:00:00 2001 From: Steffen Ritter Date: Tue, 5 Sep 2017 16:25:33 +0200 Subject: [translation] Added translation for 'subnet' filter --- modules-available/statistics/lang/de/template-tags.json | 3 ++- modules-available/statistics/lang/en/template-tags.json | 3 ++- modules-available/statistics/templates/filterbox.html | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'modules-available') diff --git a/modules-available/statistics/lang/de/template-tags.json b/modules-available/statistics/lang/de/template-tags.json index e0be0d48..02c3e4d6 100644 --- a/modules-available/statistics/lang/de/template-tags.json +++ b/modules-available/statistics/lang/de/template-tags.json @@ -69,6 +69,7 @@ "lang_showList": "Liste", "lang_showVisualization": "Visualisierung", "lang_sockets": "Sockel", + "lang_subnet": "Subnetz", "lang_tempPart": "Temp. Partition", "lang_tempPartStats": "Tempor\u00e4re Partition", "lang_thoseAreProjectors": "Diese Modellnamen werden als Beamer behandelt, auch wenn die EDID-Informationen des Ger\u00e4tes anderes berichten.", @@ -81,4 +82,4 @@ "lang_virtualCores": "Virtuelle Kerne", "lang_when": "Wann", "lang_withBadSectors": "Clients mit potentiell defekten Festplatten (mehr als 10 defekte Sektoren)" -} \ No newline at end of file +} diff --git a/modules-available/statistics/lang/en/template-tags.json b/modules-available/statistics/lang/en/template-tags.json index 4a31a5ee..c097ce37 100644 --- a/modules-available/statistics/lang/en/template-tags.json +++ b/modules-available/statistics/lang/en/template-tags.json @@ -69,6 +69,7 @@ "lang_showList": "Show list", "lang_showVisualization": "Show visualization", "lang_sockets": "Sockets", + "lang_subnet": "Subnet", "lang_tempPart": "Temp. partition", "lang_tempPartStats": "Temporary partition", "lang_thoseAreProjectors": "These model names will always be treated as beamers, even if the device's EDID data says otherwise.", @@ -81,4 +82,4 @@ "lang_virtualCores": "Virtual cores", "lang_when": "When", "lang_withBadSectors": "Clients with potentially bad HDDs (more than 10 reallocated sectors)" -} \ No newline at end of file +} diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html index 95fbab84..7cd0f617 100644 --- a/modules-available/statistics/templates/filterbox.html +++ b/modules-available/statistics/templates/filterbox.html @@ -75,7 +75,8 @@ var slxFilterNames = { clientip: '{{lang_ip}}', state: '{{lang_usageState}}', location: '{{lang_location}}', - currentuser: '{{lang_currentUser}}' + currentuser: '{{lang_currentUser}}', + subnet: '{{lang_subnet}}' }; slxLocations = {{{locations}}}; -- cgit v1.2.3-55-g7522 From 63619e1b608e7492d9e0c55ba0ddb072d194cd29 Mon Sep 17 00:00:00 2001 From: Jonathan Bauer Date: Wed, 6 Sep 2017 10:51:10 +0200 Subject: [dozmod] network shares ressource preparation for network share support --- modules-available/dozmod/api.inc.php | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'modules-available') diff --git a/modules-available/dozmod/api.inc.php b/modules-available/dozmod/api.inc.php index accfe813..b7f6c4e7 100644 --- a/modules-available/dozmod/api.inc.php +++ b/modules-available/dozmod/api.inc.php @@ -17,7 +17,7 @@ if (!Module::isAvailable('locations')) { define('LIST_URL', CONFIG_DOZMOD_URL . '/vmchooser/list'); define('VMX_URL', CONFIG_DOZMOD_URL . '/vmchooser/lecture'); -$availableRessources = ['list', 'vmx', 'test', 'netrules', 'runscript']; +$availableRessources = ['list', 'vmx', 'test', 'netrules', 'runscript', 'netshares']; /* BEGIN: A simple caching mechanism ---------------------------- */ @@ -234,7 +234,19 @@ function outputNetrules($lecture_uuid) die($value); } } - +function outputNetshares($lecture_uuid) +{ + $key = 'netshares_' . $lecture_uuid; + if (cache_has($key)) { + cache_get_passthru($key); + } else { + $value = _getVmData($lecture_uuid, 'netshares'); + if ($value === false) + return false; + cache_put($key, $value); + die($value); + } +} function outputRunscript($lecture_uuid) { $key = 'runscript_' . $lecture_uuid; @@ -312,6 +324,13 @@ if ($resource === 'netrules') { fatalDozmodUnreachable(); } +if ($resource === 'netshares') { + $lecture = readLectureParam(); + outputNetshares($lecture); + // no return on success + fatalDozmodUnreachable(); +} + if ($resource === 'runscript') { $lecture = readLectureParam(); outputRunscript($lecture); -- cgit v1.2.3-55-g7522 From da5fe90f4b8091b13abd5a5f3486dbadd528e214 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 6 Oct 2017 18:00:22 +0200 Subject: [runmode] Support returning associative array --- modules-available/runmode/inc/runmode.inc.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'modules-available') diff --git a/modules-available/runmode/inc/runmode.inc.php b/modules-available/runmode/inc/runmode.inc.php index 0f4994f4..bf20596b 100644 --- a/modules-available/runmode/inc/runmode.inc.php +++ b/modules-available/runmode/inc/runmode.inc.php @@ -64,7 +64,8 @@ class RunMode /** * @param string|\Module $module - * @return array + * @param bool true = wrap in array where key is modeid + * @return array key=machineuuid, value={'machineuuid', 'modeid', 'modedata'} */ public static function getForModule($module, $groupByModeId = false) { @@ -91,9 +92,10 @@ class RunMode * @param string|\Module $module * @param string $modeId * @param bool $detailed whether to return meta data about machine, not just machineuuid - * @return array + * @param bool $assoc use machineuuid as array key + * @return array , value={'machineuuid', 'modedata', <'hostname', 'clientip', 'macaddr', 'locationid'>} */ - public static function getForMode($module, $modeId, $detailed = false) + public static function getForMode($module, $modeId, $detailed = false, $assoc = false) { if (is_object($module)) { $module = $module->getIdentifier(); @@ -114,7 +116,11 @@ class RunMode if ($detailed && empty($row['hostname'])) { $row['hostname'] = $row['clientip']; } - $ret[] = $row; + if ($assoc) { + $ret[$row['machineuuid']] = $row; + } else { + $ret[] = $row; + } } return $ret; } -- cgit v1.2.3-55-g7522 From 2933768b0dc7d58f0b0ba7f2efcbaf1806eb275b Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 6 Oct 2017 18:00:59 +0200 Subject: [dnbd3] New module for managing dnbd3 servers - WIP --- modules-available/dnbd3/config.json | 4 + modules-available/dnbd3/inc/dnbd3rpc.inc.php | 33 ++++++++ modules-available/dnbd3/inc/dnbd3util.inc.php | 62 ++++++++++++++ modules-available/dnbd3/lang/de/messages.json | 3 + modules-available/dnbd3/lang/de/module.json | 4 + modules-available/dnbd3/lang/de/template-tags.json | 8 ++ modules-available/dnbd3/lang/en/messages.json | 3 + modules-available/dnbd3/lang/en/module.json | 4 + modules-available/dnbd3/lang/pt/module.json | 3 + modules-available/dnbd3/page.inc.php | 96 ++++++++++++++++++++++ .../dnbd3/templates/page-clientlist.html | 12 +++ .../dnbd3/templates/page-serverlist.html | 51 ++++++++++++ 12 files changed, 283 insertions(+) create mode 100644 modules-available/dnbd3/config.json create mode 100644 modules-available/dnbd3/inc/dnbd3rpc.inc.php create mode 100644 modules-available/dnbd3/inc/dnbd3util.inc.php create mode 100644 modules-available/dnbd3/lang/de/messages.json create mode 100644 modules-available/dnbd3/lang/de/module.json create mode 100644 modules-available/dnbd3/lang/de/template-tags.json create mode 100644 modules-available/dnbd3/lang/en/messages.json create mode 100644 modules-available/dnbd3/lang/en/module.json create mode 100644 modules-available/dnbd3/lang/pt/module.json create mode 100644 modules-available/dnbd3/page.inc.php create mode 100644 modules-available/dnbd3/templates/page-clientlist.html create mode 100644 modules-available/dnbd3/templates/page-serverlist.html (limited to 'modules-available') diff --git a/modules-available/dnbd3/config.json b/modules-available/dnbd3/config.json new file mode 100644 index 00000000..f06dda5c --- /dev/null +++ b/modules-available/dnbd3/config.json @@ -0,0 +1,4 @@ +{ + "category":"main.settings-server", + "dependencies":["runmode"] +} diff --git a/modules-available/dnbd3/inc/dnbd3rpc.inc.php b/modules-available/dnbd3/inc/dnbd3rpc.inc.php new file mode 100644 index 00000000..41dcefd4 --- /dev/null +++ b/modules-available/dnbd3/inc/dnbd3rpc.inc.php @@ -0,0 +1,33 @@ +fetch(PDO::FETCH_ASSOC)) { + if (!is_null($row['clientip'])) { + $ip = $row['clientip']; + } elseif (!is_null($row['fixedip'])) { + $ip = $row['fixedip']; + } else { + continue; // Huh? + } + if (!is_null($row['machineuuid'])) { + unset($dynClients[$row['machineuuid']]); + } + $server = array( + 'serverid' => $row['serverid'], + 'addr' => $ip, + ); + $servers[] = $server; + } + // See if any clients are in dnbd3 proxy mode but don't have a matching row in the dnbd3_server table + foreach ($dynClients as $client) { + Database::exec('INSERT IGNORE INTO dnbd3_server (machineuuid) VALUES (:machineuuid)', + array('machineuuid' => $client['machineuuid'])); + // Missing from $servers now but we'll handle them in the next run, so don't bother + } + // Now query them all + $NOW = time(); + foreach ($servers as $server) { + $data = Dnbd3Rpc::query(true, false, false, $server['addr']); + if (!is_array($data) || !isset($data['runId'])) { + Database::exec('UPDATE dnbd3_server SET uptime = 0, clientcount = 0 WHERE serverid = :serverid', + array('serverid' => $server['serverid'])); + continue; + } + // Seems up - since we only get absolute rx/tx values from the server, we have to prevent update race conditions + // and make sure the server was not restarted in the meantime (use runid and uptime for this) + Database::exec('UPDATE dnbd3_server SET runid = :runid, lastseen = :now, uptime = :uptime, + totalup = totalup + If(runid = :runid AND uptime <= :uptime, If(lastup < :up, :up - lastup, 0), If(:uptime < 1800, :up, 0)), + totaldown = totaldown + If(runid = :runid AND uptime <= :uptime, If(lastdown < :down, :down - lastdown, 0), If(:uptime < 1800, :up, 0)), + lastup = :up, lastdown = :down, clientcount = :clientcount + WHERE serverid = :serverid', array( + 'runid' => $data['runId'], + 'now' => $NOW, + 'uptime' => $data['uptime'], + 'up' => $data['bytesSent'], + 'down' => $data['bytesReceived'], + 'clientcount' => $data['clientCount'], + 'serverid' => $server['serverid'] + )); + } + } + +} \ No newline at end of file diff --git a/modules-available/dnbd3/lang/de/messages.json b/modules-available/dnbd3/lang/de/messages.json new file mode 100644 index 00000000..9d7c143b --- /dev/null +++ b/modules-available/dnbd3/lang/de/messages.json @@ -0,0 +1,3 @@ +{ + "server-unreachable": "Server nicht erreichbar" +} \ No newline at end of file diff --git a/modules-available/dnbd3/lang/de/module.json b/modules-available/dnbd3/lang/de/module.json new file mode 100644 index 00000000..cf748a49 --- /dev/null +++ b/modules-available/dnbd3/lang/de/module.json @@ -0,0 +1,4 @@ +{ + "module_name": "DNBD3", + "page_title": "DNBD3-Verwaltung" +} \ No newline at end of file diff --git a/modules-available/dnbd3/lang/de/template-tags.json b/modules-available/dnbd3/lang/de/template-tags.json new file mode 100644 index 00000000..8c8f6d7a --- /dev/null +++ b/modules-available/dnbd3/lang/de/template-tags.json @@ -0,0 +1,8 @@ +{ + "lang_clientCount": "Clients", + "lang_lastSeen": "Letzte Aktivit\u00e4t", + "lang_proxyServerTHead": "Server\/Proxy", + "lang_rxTotal": "Gesamt empfangen", + "lang_txTotal": "Gesamt gesendet", + "lang_uptime": "Aktuelle Laufzeit" +} \ No newline at end of file diff --git a/modules-available/dnbd3/lang/en/messages.json b/modules-available/dnbd3/lang/en/messages.json new file mode 100644 index 00000000..4c658e11 --- /dev/null +++ b/modules-available/dnbd3/lang/en/messages.json @@ -0,0 +1,3 @@ +{ + "server-unreachable": "Server not reachable" +} \ No newline at end of file diff --git a/modules-available/dnbd3/lang/en/module.json b/modules-available/dnbd3/lang/en/module.json new file mode 100644 index 00000000..d2bb6fd3 --- /dev/null +++ b/modules-available/dnbd3/lang/en/module.json @@ -0,0 +1,4 @@ +{ + "module_name": "DNBD3", + "page_title": "DNBD3 management" +} \ No newline at end of file diff --git a/modules-available/dnbd3/lang/pt/module.json b/modules-available/dnbd3/lang/pt/module.json new file mode 100644 index 00000000..8cc7f8e4 --- /dev/null +++ b/modules-available/dnbd3/lang/pt/module.json @@ -0,0 +1,3 @@ +{ + "module_name": "Log do Servidor" +} \ No newline at end of file diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php new file mode 100644 index 00000000..309680a6 --- /dev/null +++ b/modules-available/dnbd3/page.inc.php @@ -0,0 +1,96 @@ +showClientList(); + } elseif ($show === false) { + $this->showServerList(); + } else { + Util::redirect('?do=dnbd3'); + } + } + + private function showServerList() + { + $dynClients = RunMode::getForMode(Page::getModule(), 'proxy', true, true); + $res = Database::simpleQuery('SELECT serverid, machineuuid, fixedip, lastseen, uptime, totalup, totaldown, clientcount FROM dnbd3_server'); + $servers = array(); + $sort = array(); + $NOW = time(); + while ($server = $res->fetch(PDO::FETCH_ASSOC)) { + if (isset($dynClients[$server['machineuuid']])) { + $server += $dynClients[$server['machineuuid']]; + unset($dynClients[$server['machineuuid']]); + } + if ($server['uptime'] != 0) { + $server['uptime'] += ($NOW - $server['lastseen']); + } + $server['lastseen_s'] = $server['lastseen'] ? date('d.m.Y H:i', $server['lastseen']) : '-'; + $server['uptime_s'] = $server['uptime'] ? floor($server['uptime'] / 86400) . 'd ' . gmdate('H:i', $server['uptime']) : '-'; + $server['totalup_s'] = Util::readableFileSize($server['totalup']); + $server['totaldown_s'] = Util::readableFileSize($server['totaldown']); + $servers[] = $server; + $sort[] = $server['fixedip'] . '.' . $server['machineuuid']; + } + foreach ($dynClients as $server) { + $servers[] = $server; + $sort[] = 'A' . $server['machineuuid']; + } + array_multisort($sort, SORT_ASC, $servers); + Render::addTemplate('page-serverlist', array('list' => $servers)); + } + + private function showClientList() + { + $serverId = Request::get('server', false, 'int'); + if ($serverId === false) { + // TODO: Missing param + } + $server = Database::queryFirst('SELECT s.machineuuid, s.fixedip, m.clientip, m.hostname + FROM dnbd3_server s + LEFT JOIN machine m USING (machineuuid) + WHERE s.serverid = :serverId', compact('serverId')); + if ($server === false) { + // TODO: Not found + } + if (!is_null($server['clientip'])) { + $ip = $server['clientip']; + } elseif (!is_null($server['fixedip'])) { + $ip = $server['fixedip']; + } else { + $ip = '127.0.0.1'; + } + $data = Dnbd3Rpc::query(false, true, false, $ip); + if ($data === false || !isset($data['clients'])) { + Message::addError('server-unreachable'); + } else { + $sort = array(); + foreach ($data['clients'] as &$c) { + $c['bytesSent_s'] = Util::readableFileSize($c['bytesSent']); + $sort[] = $c['bytesSent']; + } + array_multisort($sort, SORT_DESC, $data['clients']); + Render::addTemplate('page-clientlist', $data); + } + } + +} diff --git a/modules-available/dnbd3/templates/page-clientlist.html b/modules-available/dnbd3/templates/page-clientlist.html new file mode 100644 index 00000000..3fd4442c --- /dev/null +++ b/modules-available/dnbd3/templates/page-clientlist.html @@ -0,0 +1,12 @@ + + {{#clients}} + + + + + {{/clients}} +
+ {{address}} + + {{bytesSent_s}} +
\ No newline at end of file diff --git a/modules-available/dnbd3/templates/page-serverlist.html b/modules-available/dnbd3/templates/page-serverlist.html new file mode 100644 index 00000000..b7fe9038 --- /dev/null +++ b/modules-available/dnbd3/templates/page-serverlist.html @@ -0,0 +1,51 @@ +
+ + +
+ + + + + + + + + + + {{#list}} + + + + + + + + + {{/list}} +
{{lang_proxyServerTHead}}{{lang_lastSeen}}{{lang_uptime}}{{lang_txTotal}}{{lang_rxTotal}}{{lang_clientCount}}
+ {{#uptime}} + + {{/uptime}} + {{^uptime}} + + {{/uptime}} + {{fixedip}} + {{#machineuuid}} + {{hostname}} ({{clientip}}) + {{/machineuuid}} + + {{lastseen_s}} + + {{uptime_s}} + + {{totalup_s}} + + {{totaldown_s}} + + {{#uptime}} + {{clientcount}} + {{/uptime}} + {{^uptime}} + - + {{/uptime}} +
\ No newline at end of file -- cgit v1.2.3-55-g7522 From 0041e188f7ef4c936eb08f26e08f229e7ce1b550 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 10 Oct 2017 17:40:51 +0200 Subject: [dnbd3] More progress, manage location restrictions for proxies --- modules-available/dnbd3/config.json | 2 +- modules-available/dnbd3/hooks/cron.inc.php | 3 + modules-available/dnbd3/hooks/runmode/config.json | 6 + modules-available/dnbd3/inc/dnbd3rpc.inc.php | 4 + modules-available/dnbd3/inc/dnbd3util.inc.php | 96 +++++++++++- modules-available/dnbd3/page.inc.php | 153 +++++++++++++++++--- .../dnbd3/templates/page-client-loclist.html | 27 ++++ .../dnbd3/templates/page-clientlist.html | 28 ++-- .../dnbd3/templates/page-header-servername.html | 1 + .../dnbd3/templates/page-server-locations.html | 96 ++++++++++++ .../dnbd3/templates/page-serverlist.html | 161 +++++++++++++++------ 11 files changed, 497 insertions(+), 80 deletions(-) create mode 100644 modules-available/dnbd3/hooks/cron.inc.php create mode 100644 modules-available/dnbd3/hooks/runmode/config.json create mode 100644 modules-available/dnbd3/templates/page-client-loclist.html create mode 100644 modules-available/dnbd3/templates/page-header-servername.html create mode 100644 modules-available/dnbd3/templates/page-server-locations.html (limited to 'modules-available') diff --git a/modules-available/dnbd3/config.json b/modules-available/dnbd3/config.json index f06dda5c..f84a4170 100644 --- a/modules-available/dnbd3/config.json +++ b/modules-available/dnbd3/config.json @@ -1,4 +1,4 @@ { "category":"main.settings-server", - "dependencies":["runmode"] + "dependencies":["locations","runmode"] } diff --git a/modules-available/dnbd3/hooks/cron.inc.php b/modules-available/dnbd3/hooks/cron.inc.php new file mode 100644 index 00000000..3da4cae4 --- /dev/null +++ b/modules-available/dnbd3/hooks/cron.inc.php @@ -0,0 +1,3 @@ +') { + $server = '127.0.0.1'; + } $url = 'http://' . $server . ':' . $port . '/query?'; if ($stats) { $url .= 'q=stats&'; diff --git a/modules-available/dnbd3/inc/dnbd3util.inc.php b/modules-available/dnbd3/inc/dnbd3util.inc.php index b04583b8..48e887b3 100644 --- a/modules-available/dnbd3/inc/dnbd3util.inc.php +++ b/modules-available/dnbd3/inc/dnbd3util.inc.php @@ -5,6 +5,7 @@ class Dnbd3Util { public static function updateServerStatus() { $dynClients = RunMode::getForMode('dnbd3', 'proxy', false, true); + $satServerIp = Property::getServerIp(); $servers = array(); $res = Database::simpleQuery('SELECT s.serverid, s.machineuuid, s.fixedip, s.lastup, s.lastdown, m.clientip FROM dnbd3_server s @@ -17,7 +18,7 @@ class Dnbd3Util { } else { continue; // Huh? } - if (!is_null($row['machineuuid'])) { + if (!is_null($row['machineuuid']) || $row['clientip'] === $satServerIp) { unset($dynClients[$row['machineuuid']]); } $server = array( @@ -32,6 +33,10 @@ class Dnbd3Util { array('machineuuid' => $client['machineuuid'])); // Missing from $servers now but we'll handle them in the next run, so don't bother } + // Same for this server - we use the special fixedip '' for it and need to prevent we don't have the + // IP address of the server itself in the list. + Database::exec('DELETE FROM dnbd3_server WHERE fixedip = :serverip', array('serverip' => $satServerIp)); + Database::exec("INSERT IGNORE INTO dnbd3_server (fixedip) VALUES ('')"); // Now query them all $NOW = time(); foreach ($servers as $server) { @@ -59,4 +64,93 @@ class Dnbd3Util { } } + /** + * A client is booting that has runmode dnbd3 proxy - set config vars accordingly. + * + * @param string $machineUuid + * @param string $mode always 'proxy' + * @param string $modeData + */ + public static function runmodeConfigHook($machineUuid, $mode, $modeData) + { + // Get all directly assigned locations + $res = Database::simpleQuery('SELECT locationid FROM dnbd3_server + INNER JOIN dnbd3_server_x_location USING (serverid) + WHERE machineuuid = :uuid', + array('uuid' => $machineUuid)); + $assignedLocs = $res->fetchAll(PDO::FETCH_ASSOC); + if (!empty($assignedLocs)) { + // Get all sub-locations too + $recursiveLocs = $assignedLocs; + $locations = Location::getLocationsAssoc(); + foreach ($assignedLocs as $l) { + if (isset($locations[$l])) { + $recursiveLocs = array_merge($recursiveLocs, $locations[$l]['children']); + } + } + $res = Database::simpleQuery('SELECT startaddr, endaddr FROM subnet WHERE locationid IN (:locs)', + array('locs' => $recursiveLocs)); + // Got subnets, build whitelist + $opt = ''; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $opt .= ' ' . self::range2Cidr($row['startaddr'], $row['endaddr']); + } + if (!empty($opt)) { + ConfigHolder::add('SLX_DNBD3_WHITELIST', $opt, 1000); + } + } + // Send list of other proxy servers + $res = Database::simpleQuery('SELECT s.fixedip, m.clientip, sxl.locationid FROM dnbd3_server s + LEFT JOIN machine m USING (machineuuid) + LEFT JOIN dnbd3_server_x_location sxl USING (serverid) + WHERE s.machineuuid <> :uuid OR s.machineuuid IS NULL', array('uuid' => $machineUuid)); + $public = array(); + $private = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $ip = $row['clientip'] ? $row['clientip'] : $row['fixedip']; + if ($ip === '') { + continue; + } + if (is_null($row['locationid'])) { + if (!array_key_exists($ip, $private)) { + $public[$ip] = $ip; + } + } else { + $private[$ip] = $ip; + } + } + if (!empty($public)) { + ConfigHolder::add('SLX_DNBD3_PUBLIC', implode(' ', $public)); + } + if (!empty($private)) { + ConfigHolder::add('SLX_DNBD3_PRIVATE', implode(' ', $private)); + } + ConfigHolder::add('SLX_ADDONS', '', 1000); + } + + /** + * Get smallest subnet in CIDR notation that covers the given range. + * The subnet denoted by the CIDR notation might actually be larger + * than the range described by $start and $end. + * + * @param int $start start address + * @param int $end end address + * @return string CIDR notation + */ + private static function range2Cidr($start, $end) + { + $bin = decbin($start ^ $end); + if ($bin === '0') + return $start; + $mask = 32 - strlen($bin); + return $start . '/' . $mask; + } + +} + +class Dnbd3ProxyConfig +{ + + public $a; + } \ No newline at end of file diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php index 309680a6..213afa03 100644 --- a/modules-available/dnbd3/page.inc.php +++ b/modules-available/dnbd3/page.inc.php @@ -11,17 +11,47 @@ class Page_Dnbd3 extends Page Message::addError('main.no-permission'); Util::redirect('?do=Main'); } - if (Request::post('re')) { + $action = Request::post('action', false, 'string'); + if ($action === 'refresh') { Dnbd3Util::updateServerStatus(); + } elseif ($action === 'delserver') { + $this->deleteServer(); + } elseif ($action === 'savelocations') { + $this->saveServerLocations(); + } + if (Request::isPost()) { Util::redirect('?do=dnbd3'); } } + private function saveServerLocations() + { + $server = $this->getServerById(); + $locids = Request::post('location', [], 'array'); + if (empty($locids)) { + Database::exec('DELETE FROM dnbd3_server_x_location WHERE serverid = :serverid', + array('serverid' => $server['serverid'])); + } else { + Database::exec('DELETE FROM dnbd3_server_x_location WHERE serverid = :serverid AND locationid NOT IN (:lids)', + array('serverid' => $server['serverid'], 'lids' => $locids)); + foreach ($locids as $lid) { + Database::exec('INSERT IGNORE INTO dnbd3_server_x_location (serverid, locationid) VALUES (:serverid, :lid)', + array('serverid' => $server['serverid'], 'lid' => $lid)); + } + } + } + + /* + * RENDER + */ + protected function doRender() { $show = Request::get('show', false, 'string'); if ($show === 'clients') { $this->showClientList(); + } elseif ($show === 'locations') { + $this->showServerLocationEdit(); } elseif ($show === false) { $this->showServerList(); } else { @@ -32,7 +62,11 @@ class Page_Dnbd3 extends Page private function showServerList() { $dynClients = RunMode::getForMode(Page::getModule(), 'proxy', true, true); - $res = Database::simpleQuery('SELECT serverid, machineuuid, fixedip, lastseen, uptime, totalup, totaldown, clientcount FROM dnbd3_server'); + $res = Database::simpleQuery('SELECT s.serverid, s.machineuuid, s.fixedip, s.lastseen, + s.uptime, s.totalup, s.totaldown, s.clientcount, Count(sxl.locationid) AS locations + FROM dnbd3_server s + LEFT JOIN dnbd3_server_x_location sxl USING (serverid) + GROUP BY s.serverid'); $servers = array(); $sort = array(); $NOW = time(); @@ -48,12 +82,17 @@ class Page_Dnbd3 extends Page $server['uptime_s'] = $server['uptime'] ? floor($server['uptime'] / 86400) . 'd ' . gmdate('H:i', $server['uptime']) : '-'; $server['totalup_s'] = Util::readableFileSize($server['totalup']); $server['totaldown_s'] = Util::readableFileSize($server['totaldown']); + $server['self'] = ($server['fixedip'] === ''); $servers[] = $server; - $sort[] = $server['fixedip'] . '.' . $server['machineuuid']; + if ($server['self']) { + $sort[] = '---'; + } else { + $sort[] = $server['fixedip'] . '.' . $server['machineuuid']; + } } foreach ($dynClients as $server) { $servers[] = $server; - $sort[] = 'A' . $server['machineuuid']; + $sort[] = '-' . $server['machineuuid']; } array_multisort($sort, SORT_ASC, $servers); Render::addTemplate('page-serverlist', array('list' => $servers)); @@ -61,11 +100,94 @@ class Page_Dnbd3 extends Page private function showClientList() { - $serverId = Request::get('server', false, 'int'); + $server = $this->getServerById(); + Render::addTemplate('page-header-servername', $server); + $data = Dnbd3Rpc::query(false, true, false, $server['ip']); + if ($data === false || !isset($data['clients'])) { + Message::addError('server-unreachable'); + return; + } + $ips = array(); + $sort = array(); + foreach ($data['clients'] as &$c) { + $c['bytesSent_s'] = Util::readableFileSize($c['bytesSent']); + $sort[] = $c['bytesSent']; + $ips[] = preg_replace('/:\d+$/', '', $c['address']); + } + array_multisort($sort, SORT_DESC, $data['clients']); + 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')); + $locCount = Location::getLocationsAssoc(); + $locCount[0] = array( + 'locationname' => '/', + 'depth' => 0, + 'recCount' => 0, + ); + foreach ($locCount as &$loc) { + $loc['recCount'] = 0; + } + $showLocs = false; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + settype($row['locationid'], 'int'); + $loc =& $locCount[$row['locationid']]; + $loc['clientCount'] = $row['cnt']; + $loc['recCount'] += $row['cnt']; + if ($row['locationid'] !== 0) { + $showLocs = true; + } + $loc['keep'] = true; + if (isset($loc['parents'])) { + foreach ($loc['parents'] as $p) { + $locCount[$p]['keep'] = true; + $locCount[$p]['recCount'] += $row['cnt']; + } + } + } + if ($showLocs) { + $locCount = array_filter($locCount, function ($v) { return isset($v['keep']); }); + Render::addTemplate('page-client-loclist', array('list' => array_values($locCount))); + } + Render::addTemplate('page-clientlist', $data); + Render::closeTag('div'); + } + + private function showServerLocationEdit() + { + $server = $this->getServerById(); + // Get selected ones + $res = Database::simpleQuery('SELECT locationid FROM dnbd3_server_x_location WHERE serverid = :serverid', + array('serverid' => $server['serverid'])); + $selectedLocations = array(); + while ($loc = $res->fetchColumn(0)) { + $selectedLocations[$loc] = true; + } + // Build location list + $server['locations'] = array_values(Location::getSubnetsByLocation()); + $filtered = array(); + foreach ($server['locations'] as &$loc) { + $filtered['l'.$loc['locationid']] = array( + 'children' => $loc['children'], + 'subnets' => $loc['subnets'] + ); + if (isset($selectedLocations[$loc['locationid']])) { + $loc['checked_s'] = 'checked'; + } + } + unset($loc); + $server['jsonLocations'] = json_encode($filtered); + Render::addTemplate('page-server-locations', $server); + } + + private function getServerById($serverId = false) + { + if ($serverId === false) { + $serverId = Request::any('server', false, 'int'); + } if ($serverId === false) { // TODO: Missing param } - $server = Database::queryFirst('SELECT s.machineuuid, s.fixedip, m.clientip, m.hostname + $server = Database::queryFirst('SELECT s.serverid, s.machineuuid, s.fixedip, m.clientip, m.hostname FROM dnbd3_server s LEFT JOIN machine m USING (machineuuid) WHERE s.serverid = :serverId', compact('serverId')); @@ -73,24 +195,13 @@ class Page_Dnbd3 extends Page // TODO: Not found } if (!is_null($server['clientip'])) { - $ip = $server['clientip']; + $server['ip'] = $server['clientip']; } elseif (!is_null($server['fixedip'])) { - $ip = $server['fixedip']; + $server['ip'] = $server['fixedip']; } else { - $ip = '127.0.0.1'; - } - $data = Dnbd3Rpc::query(false, true, false, $ip); - if ($data === false || !isset($data['clients'])) { - Message::addError('server-unreachable'); - } else { - $sort = array(); - foreach ($data['clients'] as &$c) { - $c['bytesSent_s'] = Util::readableFileSize($c['bytesSent']); - $sort[] = $c['bytesSent']; - } - array_multisort($sort, SORT_DESC, $data['clients']); - Render::addTemplate('page-clientlist', $data); + $server['ip'] = '127.0.0.1'; } + return $server; } } diff --git a/modules-available/dnbd3/templates/page-client-loclist.html b/modules-available/dnbd3/templates/page-client-loclist.html new file mode 100644 index 00000000..67c90683 --- /dev/null +++ b/modules-available/dnbd3/templates/page-client-loclist.html @@ -0,0 +1,27 @@ +
+

{{lang_clientsByLocation}}

+ + + + + + + + {{#list}} + + + + + + {{/list}} +
{{lang_location}}{{lang_count}}{{lang_recursiveCount}}
+ {{#depth}} +
+ {{/depth}} + {{locationname}} +
+ {{clientCount}} + + {{recCount}} +
+
\ No newline at end of file diff --git a/modules-available/dnbd3/templates/page-clientlist.html b/modules-available/dnbd3/templates/page-clientlist.html index 3fd4442c..9e7cec4c 100644 --- a/modules-available/dnbd3/templates/page-clientlist.html +++ b/modules-available/dnbd3/templates/page-clientlist.html @@ -1,12 +1,20 @@ - - {{#clients}} +
+

{{lang_clientList}}

+ +
- - + + - {{/clients}} -
- {{address}} - - {{bytesSent_s}} - {{lang_client}}{{lang_bytesSent}}
\ No newline at end of file + {{#clients}} + + + {{address}} + + + {{bytesSent_s}} + + + {{/clients}} + + \ No newline at end of file diff --git a/modules-available/dnbd3/templates/page-header-servername.html b/modules-available/dnbd3/templates/page-header-servername.html new file mode 100644 index 00000000..6f3f1b7f --- /dev/null +++ b/modules-available/dnbd3/templates/page-header-servername.html @@ -0,0 +1 @@ +

{{ip}}

\ No newline at end of file diff --git a/modules-available/dnbd3/templates/page-server-locations.html b/modules-available/dnbd3/templates/page-server-locations.html new file mode 100644 index 00000000..8e76a68d --- /dev/null +++ b/modules-available/dnbd3/templates/page-server-locations.html @@ -0,0 +1,96 @@ +

{{lang_manageAccessTo}} {{ip}}

+ +

{{lang_proxyLocationText}}

+ +
+ + + +
+ +
+ +
+
+

{{lang_allowedSubnets}}

+
+ +
+
+
+

{{lang_locations}}

+ {{#locations}} +
+ {{#depth}} +
+ {{/depth}} + + +
+ {{/locations}} +
+
+ +
+ +
+
+ + \ No newline at end of file diff --git a/modules-available/dnbd3/templates/page-serverlist.html b/modules-available/dnbd3/templates/page-serverlist.html index b7fe9038..e50c6bcb 100644 --- a/modules-available/dnbd3/templates/page-serverlist.html +++ b/modules-available/dnbd3/templates/page-serverlist.html @@ -1,51 +1,118 @@ +

{{lang_dnbd3Management}}

+

{{lang_dnbd3IntroText}}

+
- +

+ {{lang_serverList}} + +

+
+
+ + + + + + + + + + + + + + {{#list}} + + + + + + + + + + + {{/list}} +
{{lang_proxyServerTHead}}{{lang_clientCount}}{{lang_lastSeen}}{{lang_uptime}}{{lang_txTotal}}{{lang_rxTotal}}{{lang_locations}} 
+ {{#uptime}} + + {{/uptime}} + {{^uptime}} + + {{/uptime}} + {{fixedip}} + {{#machineuuid}} + {{clientip}} +
{{hostname}}
+ {{/machineuuid}} +
+ {{#uptime}} + {{clientcount}} + {{/uptime}} + {{^uptime}} + - + {{/uptime}} + + {{lastseen_s}} + + {{uptime_s}} + + {{totalup_s}} + + {{totaldown_s}} + + {{^self}} + {{^locations}} + {{lang_global}} + {{/locations}} + {{#locations}} + {{locations}} + {{/locations}} + + + + {{/self}} + + {{^self}} + + {{/self}} +
- - - - - - - - - - {{#list}} - - - - - - - - - {{/list}} -
{{lang_proxyServerTHead}}{{lang_lastSeen}}{{lang_uptime}}{{lang_txTotal}}{{lang_rxTotal}}{{lang_clientCount}}
- {{#uptime}} - - {{/uptime}} - {{^uptime}} - - {{/uptime}} - {{fixedip}} - {{#machineuuid}} - {{hostname}} ({{clientip}}) - {{/machineuuid}} - - {{lastseen_s}} - - {{uptime_s}} - - {{totalup_s}} - - {{totaldown_s}} - - {{#uptime}} - {{clientcount}} - {{/uptime}} - {{^uptime}} - - - {{/uptime}} -
\ No newline at end of file +
+ + + + {{lang_addManagedProxy}} + +
+ + + +
\ No newline at end of file -- cgit v1.2.3-55-g7522 From df6fdbdb110ea28de4f5b9f540e01313ec217407 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 11 Oct 2017 13:19:19 +0200 Subject: [dnbd3] Fix CIDR generation for proxies, add baseconfig hook for clients --- .../dnbd3/baseconfig/getconfig.inc.php | 46 ++++++++++++++++++++++ modules-available/dnbd3/inc/dnbd3.inc.php | 17 ++++++++ modules-available/dnbd3/inc/dnbd3util.inc.php | 29 ++++++++------ 3 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 modules-available/dnbd3/baseconfig/getconfig.inc.php create mode 100644 modules-available/dnbd3/inc/dnbd3.inc.php (limited to 'modules-available') diff --git a/modules-available/dnbd3/baseconfig/getconfig.inc.php b/modules-available/dnbd3/baseconfig/getconfig.inc.php new file mode 100644 index 00000000..ae4d2924 --- /dev/null +++ b/modules-available/dnbd3/baseconfig/getconfig.inc.php @@ -0,0 +1,46 @@ + $locationIds)); +// Lookup of priority - first index (0) will be closest location in chain +$locationsAssoc = array_flip($locationIds); +$servers = array(); +while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['fixedip'] === '') { + $row['fixedip'] = Property::getServerIp(); + $defPrio = 2000; + } else { + $defPrio = 1000; + } + $ip = $row['clientip'] ? $row['clientip'] : $row['fixedip']; + if ($defPrio === 1000 && is_null($row['locationid'])) { + $serverLoc = Location::getFromIp($ip); + if ($serverLoc !== false) { + $row['locationid'] = $serverLoc; + } + } + $old = isset($servers[$ip]) ? $servers[$ip] : $defPrio; + if (is_null($row['locationid']) || !isset($locationsAssoc[$row['locationid']])) { + $servers[$ip] = min($defPrio, $old); + } else { + $servers[$ip] = min($locationsAssoc[$row['locationid']], $old); + } +} + +asort($servers, SORT_NUMERIC | SORT_ASC); +ConfigHolder::add('SLX_DNBD3_SERVERS', implode(' ', array_keys($servers))); diff --git a/modules-available/dnbd3/inc/dnbd3.inc.php b/modules-available/dnbd3/inc/dnbd3.inc.php new file mode 100644 index 00000000..905bdc68 --- /dev/null +++ b/modules-available/dnbd3/inc/dnbd3.inc.php @@ -0,0 +1,17 @@ + $satServerIp)); Database::exec("INSERT IGNORE INTO dnbd3_server (fixedip) VALUES ('')"); + // Delete orphaned entires with machineuuid from dnbd3_server where we don't have a runmode entry + Database::exec('DELETE s FROM dnbd3_server s + LEFT JOIN runmode r USING (machineuuid) + WHERE s.machineuuid IS NOT NULL AND r.module IS NULL'); // Now query them all $NOW = time(); foreach ($servers as $server) { @@ -78,7 +82,10 @@ class Dnbd3Util { INNER JOIN dnbd3_server_x_location USING (serverid) WHERE machineuuid = :uuid', array('uuid' => $machineUuid)); - $assignedLocs = $res->fetchAll(PDO::FETCH_ASSOC); + $assignedLocs = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $assignedLocs[] = $row['locationid']; + } if (!empty($assignedLocs)) { // Get all sub-locations too $recursiveLocs = $assignedLocs; @@ -89,8 +96,9 @@ class Dnbd3Util { } } $res = Database::simpleQuery('SELECT startaddr, endaddr FROM subnet WHERE locationid IN (:locs)', - array('locs' => $recursiveLocs)); + array('locs' => array_values($recursiveLocs))); // Got subnets, build whitelist + // TODO: Coalesce overlapping ranges $opt = ''; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $opt .= ' ' . self::range2Cidr($row['startaddr'], $row['endaddr']); @@ -126,6 +134,10 @@ class Dnbd3Util { ConfigHolder::add('SLX_DNBD3_PRIVATE', implode(' ', $private)); } ConfigHolder::add('SLX_ADDONS', '', 1000); + ConfigHolder::add('SLX_SHUTDOWN_TIMEOUT', '', 1000); + ConfigHolder::add('SLX_SHUTDOWN_SCHEDULE', '', 1000); + ConfigHolder::add('SLX_REBOOT_TIMEOUT', '', 1000); + ConfigHolder::add('SLX_REBOOT_SCHEDULE', '', 1000); } /** @@ -139,18 +151,11 @@ class Dnbd3Util { */ private static function range2Cidr($start, $end) { - $bin = decbin($start ^ $end); + $bin = decbin((int)$start ^ (int)$end); if ($bin === '0') - return $start; + return long2ip($start); $mask = 32 - strlen($bin); - return $start . '/' . $mask; + return long2ip($start) . '/' . $mask; } } - -class Dnbd3ProxyConfig -{ - - public $a; - -} \ No newline at end of file -- cgit v1.2.3-55-g7522 From 2bf954897109fc761a6aa39bfc4479e087671200 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 11 Oct 2017 16:01:18 +0200 Subject: [dnbd3] Implement adding and deleting servers --- modules-available/dnbd3/inc/dnbd3util.inc.php | 7 +- modules-available/dnbd3/page.inc.php | 83 ++++++++++++++++++++- .../dnbd3/templates/page-serverlist.html | 86 ++++++++++++++++++++-- 3 files changed, 168 insertions(+), 8 deletions(-) (limited to 'modules-available') diff --git a/modules-available/dnbd3/inc/dnbd3util.inc.php b/modules-available/dnbd3/inc/dnbd3util.inc.php index 722cc5e3..45ae6135 100644 --- a/modules-available/dnbd3/inc/dnbd3util.inc.php +++ b/modules-available/dnbd3/inc/dnbd3util.inc.php @@ -18,8 +18,13 @@ class Dnbd3Util { } else { continue; // Huh? } - if (!is_null($row['machineuuid']) || $row['clientip'] === $satServerIp) { + if (!is_null($row['machineuuid'])) { unset($dynClients[$row['machineuuid']]); + if ($row['clientip'] === $satServerIp) { + // Lolwut, sat server is openslx client configured for proxy mode!? baleeted. + RunMode::setRunMode($row['machineuuid'], 'dnbd3', null, null, null); + continue; + } } $server = array( 'serverid' => $row['serverid'], diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php index 213afa03..3489cc5b 100644 --- a/modules-available/dnbd3/page.inc.php +++ b/modules-available/dnbd3/page.inc.php @@ -16,6 +16,8 @@ class Page_Dnbd3 extends Page Dnbd3Util::updateServerStatus(); } elseif ($action === 'delserver') { $this->deleteServer(); + } elseif ($action === 'addserver') { + $this->addServer(); } elseif ($action === 'savelocations') { $this->saveServerLocations(); } @@ -41,6 +43,45 @@ class Page_Dnbd3 extends Page } } + private function addServer() + { + $ip = Request::post('newip', false, 'string'); + if ($ip === false) { + Message::addError('main.parameter-missing', 'ip'); + return; + } + $ip = ip2long(trim($ip)); + if ($ip !== false) { + $ip = long2ip($ip); + } + if ($ip === false) { + Message::addError('invalid-ipv4', $ip); + return; + } + $res = Database::queryFirst('SELECT serverid FROM dnbd3_server s + LEFT JOIN machine m USING (machineuuid) + WHERE s.fixedip = :ip OR m.clientip = :ip', compact('ip')); + if ($res !== false) { + Message::addError('server-already-exists', $ip); + return; + } + Database::exec('INSERT INTO dnbd3_server (fixedip) VALUES (:ip)', compact('ip')); + Message::addSuccess('server-added', $ip); + } + + private function deleteServer() + { + $server = $this->getServerById(); + if ($server['fixedip'] === '') + return; + if (!is_null($server['machineuuid'])) { + RunMode::setRunMode($server['machineuuid'], 'dnbd3', null, null, null); + } + Database::exec('DELETE FROM dnbd3_server WHERE serverid = :serverid', + array('serverid' => $server['serverid'])); + Message::addSuccess('server-deleted', $server['ip']); + } + /* * RENDER */ @@ -185,14 +226,16 @@ class Page_Dnbd3 extends Page $serverId = Request::any('server', false, 'int'); } if ($serverId === false) { - // TODO: Missing param + Message::addError('parameter-missing', 'server'); + Util::redirect('?do=dnbd3'); } $server = Database::queryFirst('SELECT s.serverid, s.machineuuid, s.fixedip, m.clientip, m.hostname FROM dnbd3_server s LEFT JOIN machine m USING (machineuuid) WHERE s.serverid = :serverId', compact('serverId')); if ($server === false) { - // TODO: Not found + Message::addError('server-non-existent', 'server'); + Util::redirect('?do=dnbd3'); } if (!is_null($server['clientip'])) { $server['ip'] = $server['clientip']; @@ -204,4 +247,40 @@ class Page_Dnbd3 extends Page return $server; } + /* + * AJAX + */ + + protected function doAjax() + { + $action = Request::post('action', false, 'string'); + if ($action === 'servertest') { + Header('Content-Type: application/json; charset=utf-8'); + $ip = Request::post('ip', false, 'string'); + if ($ip === false) + die('{"error": "Missing parameter", "fatal": true}'); + $ip = ip2long(trim($ip)); + if ($ip !== false) { + $ip = long2ip($ip); + } + if ($ip === false) + die('{"error": "Supports IPv4 only", "fatal": true}'); + // Dup? + $res = Database::queryFirst('SELECT serverid FROM dnbd3_server s + LEFT JOIN machine m USING (machineuuid) + WHERE s.fixedip = :ip OR m.clientip = :ip', compact('ip')); + if ($res !== false) + die('{"error": "Server with this IP already exists", "fatal": true}'); + // Query + $reply = Dnbd3Rpc::query(true, false, false, $ip); + if ($reply === false) + die('{"error": "Could not reach server"}'); + if (!is_array($reply)) + die('{"error": "No JSON received from server"}'); + if (!isset($reply['uptime']) || !isset($reply['clientCount'])) + die('{"error": "Reply does not suggest this is a dnbd3 server"}'); + echo json_encode($reply); + } + } + } diff --git a/modules-available/dnbd3/templates/page-serverlist.html b/modules-available/dnbd3/templates/page-serverlist.html index e50c6bcb..d9d02430 100644 --- a/modules-available/dnbd3/templates/page-serverlist.html +++ b/modules-available/dnbd3/templates/page-serverlist.html @@ -72,7 +72,9 @@ {{^self}} - + {{/self}} @@ -101,12 +103,22 @@ -
\ No newline at end of file +
+ + \ No newline at end of file -- cgit v1.2.3-55-g7522 From dcc1eb1329c3d7696490b28c473ce7178ea8cc5c Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 12 Oct 2017 10:04:56 +0200 Subject: [dnbd3] sadf --- modules-available/dnbd3/templates/page-serverlist.html | 1 - 1 file changed, 1 deletion(-) (limited to 'modules-available') diff --git a/modules-available/dnbd3/templates/page-serverlist.html b/modules-available/dnbd3/templates/page-serverlist.html index d9d02430..76f9ca35 100644 --- a/modules-available/dnbd3/templates/page-serverlist.html +++ b/modules-available/dnbd3/templates/page-serverlist.html @@ -139,7 +139,6 @@ document.addEventListener('DOMContentLoaded', function () { const $save = $('#savebtn'); const changeFunc = function() { - console.log('sadf'); $save.prop('disabled', true); }; $ip.change(changeFunc).keypress(changeFunc); -- cgit v1.2.3-55-g7522 From 025019a7a7da442648855716c6eb77e5ce5e627e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 12 Oct 2017 16:14:12 +0200 Subject: [runmode] Return lastseen too in detailed mode --- modules-available/runmode/inc/runmode.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'modules-available') diff --git a/modules-available/runmode/inc/runmode.inc.php b/modules-available/runmode/inc/runmode.inc.php index bf20596b..780f12c9 100644 --- a/modules-available/runmode/inc/runmode.inc.php +++ b/modules-available/runmode/inc/runmode.inc.php @@ -93,7 +93,8 @@ class RunMode * @param string $modeId * @param bool $detailed whether to return meta data about machine, not just machineuuid * @param bool $assoc use machineuuid as array key - * @return array , value={'machineuuid', 'modedata', <'hostname', 'clientip', 'macaddr', 'locationid'>} + * @return array , value={'machineuuid', 'modedata', + * <'hostname', 'clientip', 'macaddr', 'locationid', 'lastseen'>} */ public static function getForMode($module, $modeId, $detailed = false, $assoc = false) { @@ -101,7 +102,7 @@ class RunMode $module = $module->getIdentifier(); } if ($detailed) { - $sel = ', m.hostname, m.clientip, m.macaddr, m.locationid'; + $sel = ', m.hostname, m.clientip, m.macaddr, m.locationid, m.lastseen'; $join = 'INNER JOIN machine m USING (machineuuid)'; } else { $join = $sel = ''; -- cgit v1.2.3-55-g7522 From e10e538a0c46012175b98f8fbda6910a1295a722 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 12 Oct 2017 16:14:39 +0200 Subject: [dnbd3] Show free space, fix styling, add help texts and strings (de) --- modules-available/dnbd3/inc/dnbd3rpc.inc.php | 10 +- modules-available/dnbd3/inc/dnbd3util.inc.php | 8 +- modules-available/dnbd3/lang/de/messages.json | 5 + modules-available/dnbd3/lang/de/template-tags.json | 34 ++- modules-available/dnbd3/page.inc.php | 59 +++- .../dnbd3/templates/page-server-locations.html | 2 +- .../dnbd3/templates/page-serverlist.html | 326 +++++++++++++++------ 7 files changed, 331 insertions(+), 113 deletions(-) (limited to 'modules-available') diff --git a/modules-available/dnbd3/inc/dnbd3rpc.inc.php b/modules-available/dnbd3/inc/dnbd3rpc.inc.php index 6134489a..27713bfb 100644 --- a/modules-available/dnbd3/inc/dnbd3rpc.inc.php +++ b/modules-available/dnbd3/inc/dnbd3rpc.inc.php @@ -5,14 +5,15 @@ class Dnbd3Rpc { /** * Query given DNBD3 server for status information. * + * @param string $server server address + * @param int $port server port * @param bool $stats include general stats * @param bool $clients include client list * @param bool $images include image list - * @param string $server server address - * @param int $port server port + * @param bool $diskSpace include disk space stats * @return false|array the queried data as an array, or false on error */ - public static function query($stats, $clients, $images, $server, $port = 5003) + public static function query($server, $port, $stats, $clients, $images, $diskSpace) { // Special case - local server if ($server === '') { @@ -28,6 +29,9 @@ class Dnbd3Rpc { if ($images) { $url .= 'q=images&'; } + if ($diskSpace) { + $url .= 'q=space&'; + } $str = Download::asString($url, 3, $code); if ($str === false || $code !== 200) return false; diff --git a/modules-available/dnbd3/inc/dnbd3util.inc.php b/modules-available/dnbd3/inc/dnbd3util.inc.php index 45ae6135..ae5e0cd7 100644 --- a/modules-available/dnbd3/inc/dnbd3util.inc.php +++ b/modules-available/dnbd3/inc/dnbd3util.inc.php @@ -49,7 +49,7 @@ class Dnbd3Util { // Now query them all $NOW = time(); foreach ($servers as $server) { - $data = Dnbd3Rpc::query(true, false, false, $server['addr']); + $data = Dnbd3Rpc::query($server['addr'], 5003, true, false, false, true); if (!is_array($data) || !isset($data['runId'])) { Database::exec('UPDATE dnbd3_server SET uptime = 0, clientcount = 0 WHERE serverid = :serverid', array('serverid' => $server['serverid'])); @@ -60,7 +60,7 @@ class Dnbd3Util { Database::exec('UPDATE dnbd3_server SET runid = :runid, lastseen = :now, uptime = :uptime, totalup = totalup + If(runid = :runid AND uptime <= :uptime, If(lastup < :up, :up - lastup, 0), If(:uptime < 1800, :up, 0)), totaldown = totaldown + If(runid = :runid AND uptime <= :uptime, If(lastdown < :down, :down - lastdown, 0), If(:uptime < 1800, :up, 0)), - lastup = :up, lastdown = :down, clientcount = :clientcount + lastup = :up, lastdown = :down, clientcount = :clientcount, disktotal = :disktotal, diskfree = :diskfree WHERE serverid = :serverid', array( 'runid' => $data['runId'], 'now' => $NOW, @@ -68,7 +68,9 @@ class Dnbd3Util { 'up' => $data['bytesSent'], 'down' => $data['bytesReceived'], 'clientcount' => $data['clientCount'], - 'serverid' => $server['serverid'] + 'serverid' => $server['serverid'], + 'disktotal' => $data['spaceTotal'], + 'diskfree' => $data['spaceFree'], )); } } diff --git a/modules-available/dnbd3/lang/de/messages.json b/modules-available/dnbd3/lang/de/messages.json index 9d7c143b..b5f455dd 100644 --- a/modules-available/dnbd3/lang/de/messages.json +++ b/modules-available/dnbd3/lang/de/messages.json @@ -1,3 +1,8 @@ { + "invalid-ipv4": "{{0}} ist keine g\u00fcltige IPv4-Adresse", + "server-added": "Server {{0}} hinzugef\u00fcgt", + "server-already-exists": "Server {{0}} existiert bereits", + "server-deleted": "Server {{0}} gel\u00f6scht", + "server-non-existent": "Server {{0}} existiert nicht", "server-unreachable": "Server nicht erreichbar" } \ No newline at end of file diff --git a/modules-available/dnbd3/lang/de/template-tags.json b/modules-available/dnbd3/lang/de/template-tags.json index 8c8f6d7a..0593950c 100644 --- a/modules-available/dnbd3/lang/de/template-tags.json +++ b/modules-available/dnbd3/lang/de/template-tags.json @@ -1,8 +1,40 @@ { + "lang_addServer": "Server hinzuf\u00fcgen", + "lang_allowedSubnets": "Zum Zugriff freigegebene Subnets", + "lang_bytesSent": "Gesendet", + "lang_changeDnbd3Status": "DNBD3 ein-\/ausschalten", + "lang_client": "Client", "lang_clientCount": "Clients", + "lang_clientList": "Liste der Clients", + "lang_clientsByLocation": "Clients nach Raum\/Ort", + "lang_count": "Anzahl", + "lang_disabled": "Deaktiviert", + "lang_diskFree": "Freier Speicher", + "lang_dnbd3IntroText": "DNBD3 ist ganz toll. Einfach einschalten und los gehts, zu beachten gibt es rein gar nichts!", + "lang_dnbd3Management": "DNBD3 Verwaltung", + "lang_dnbd3Status": "DNBD3 Status", + "lang_enableDnbd3": "DNBD3 aktivieren", + "lang_enabled": "Aktiviert", + "lang_enterIpOfServer": "Bitte geben Sie die IP-Adresse des hinzuzuf\u00fcgenden Servers ein", + "lang_externalServer": "Externer DNBD3-Server", + "lang_externalServerAdd": "Externen Server hinzuf\u00fcgen", + "lang_externalServerHelp": "Ein externer Server wird nicht \u00fcber den Satellitenserver konfiguriert und verwaltet. Das Installieren, Einrichten und ggf. Aktualisieren der DNBD3-Serversoftware muss manuell durchgef\u00fchrt werden.\r\nDies bietet mehr Flexibilit\u00e4t bei der Konfiguration und Anpassung, z.B. bei der Verwendung von RAID- oder bcache-Setups, oder wenn der DNBD3-Server auf einer Maschine laufen soll, die noch andere Services bereitstellt.\r\nWeitere Informationen dazu finden Sie im Wiki.", + "lang_global": "Global", "lang_lastSeen": "Letzte Aktivit\u00e4t", + "lang_location": "Ort", + "lang_locations": "Orte", + "lang_manageAccessTo": "Zugriff auf Server festlegen:", + "lang_managedServer": "Automatisch konfigurierter DNBD3-Proxy", + "lang_managedServerAdd": "Automatisch konfigurierten Proxy hinzuf\u00fcgen", + "lang_managedServerHelp": "Automatisch konfigurierte DNBD3-Proxies booten wie gew\u00f6hnliche bwLehrpool-Clients via PXE \u00fcber den Satelliten-Server. Sobald ein bwLehrpool-Client als DNBD3-Proxy konfiguriert wird, erh\u00e4lt er beim Booten eine gesonderte Konfiguration, sodass er fortan exklusiv als DNBD3-Proxy arbeitet, und nicht mehr als Arbeitsstation zur Verf\u00fcgung steht.\r\nDer Vorteil ist, dass die Konfiguration automatisiert erfolgt, und durch w\u00f6chentliche Reboots sichergestellt wird, dass eventuelle Updates des MiniLinux angewendet werden.\r\nIn diesem Fall legen Sie bitte eine Partition mit der ID 45 auf der Festplatte des Proxy-Servers an; diese wird persistent Behandelt und im Gegensatz zur ID44-Partition nicht beim Booten formatiert. Generell sollte diese Partition so gro\u00df wie m\u00f6glich sein, abh\u00e4ngig von der Anzahl der genutzten VMs. Bei Platzmangel l\u00f6scht der Proxy automatisch die VM, die am l\u00e4ngsten nicht verwendet wurde, um neuen VMs Platz zu machen.\r\nWeitere Informationen dazu finden Sie im Wiki.", + "lang_proxyLocationText": "Bla bla bla BLA!!!!", "lang_proxyServerTHead": "Server\/Proxy", + "lang_recursiveCount": "Rekursiv", "lang_rxTotal": "Gesamt empfangen", + "lang_serverList": "Serverliste", + "lang_storageSize": "Speichergr\u00f6\u00dfe", + "lang_test": "Testen", "lang_txTotal": "Gesamt gesendet", - "lang_uptime": "Aktuelle Laufzeit" + "lang_uptime": "Aktuelle Laufzeit", + "lang_wantToDelete": "Wollen Sie diesen Server wirklich entfernen? (Rebooten\/Ausschalten muss in diesem Fall manuell vorgenommen werden)" } \ No newline at end of file diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php index 3489cc5b..a2d47f1e 100644 --- a/modules-available/dnbd3/page.inc.php +++ b/modules-available/dnbd3/page.inc.php @@ -20,12 +20,20 @@ class Page_Dnbd3 extends Page $this->addServer(); } elseif ($action === 'savelocations') { $this->saveServerLocations(); + } elseif ($action === 'toggle-usage') { + $this->toggleUsage(); } if (Request::isPost()) { Util::redirect('?do=dnbd3'); } } + private function toggleUsage() + { + $enabled = Request::post('enabled', false, 'bool'); + Dnbd3::setEnabled($enabled); + } + private function saveServerLocations() { $server = $this->getServerById(); @@ -103,8 +111,8 @@ class Page_Dnbd3 extends Page private function showServerList() { $dynClients = RunMode::getForMode(Page::getModule(), 'proxy', true, true); - $res = Database::simpleQuery('SELECT s.serverid, s.machineuuid, s.fixedip, s.lastseen, - s.uptime, s.totalup, s.totaldown, s.clientcount, Count(sxl.locationid) AS locations + $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 FROM dnbd3_server s LEFT JOIN dnbd3_server_x_location sxl USING (serverid) GROUP BY s.serverid'); @@ -117,33 +125,54 @@ class Page_Dnbd3 extends Page unset($dynClients[$server['machineuuid']]); } if ($server['uptime'] != 0) { - $server['uptime'] += ($NOW - $server['lastseen']); + $server['uptime'] += ($NOW - $server['dnbd3lastseen']); } - $server['lastseen_s'] = $server['lastseen'] ? date('d.m.Y H:i', $server['lastseen']) : '-'; + $server['dnbd3lastseen_s'] = $server['dnbd3lastseen'] ? date('d.m.Y H:i', $server['dnbd3lastseen']) : '-'; $server['uptime_s'] = $server['uptime'] ? floor($server['uptime'] / 86400) . 'd ' . gmdate('H:i', $server['uptime']) : '-'; $server['totalup_s'] = Util::readableFileSize($server['totalup']); $server['totaldown_s'] = Util::readableFileSize($server['totaldown']); + if ($server['disktotal'] > 0) { + $server['disktotal_s'] = Util::readableFileSize($server['disktotal']); + $server['diskfree_s'] = Util::readableFileSize($server['diskfree']); + $server['diskUsePercent'] = floor(100 - 100 * $server['diskfree'] / $server['disktotal']); + } else { + $server['disktotal_s'] = '?'; + $server['diskfree_s'] = '?'; + $server['diskUsePercent'] = 0; + } $server['self'] = ($server['fixedip'] === ''); - $servers[] = $server; + if (isset($server['clientip']) && !is_null($server['clientip'])) { + if ($NOW - $server['lastseen'] > 360) { + $server['slxDown'] = true; + } else { + $server['slxOk'] = true; + } + } if ($server['self']) { $sort[] = '---'; } else { $sort[] = $server['fixedip'] . '.' . $server['machineuuid']; } + $servers[] = $server; } foreach ($dynClients as $server) { $servers[] = $server; $sort[] = '-' . $server['machineuuid']; + Database::exec('INSERT INTO dnbd3_server (machineuuid) VALUES (:uuid)', array('uuid' => $server['machineuuid'])); } array_multisort($sort, SORT_ASC, $servers); - Render::addTemplate('page-serverlist', array('list' => $servers)); + Render::addTemplate('page-serverlist', array( + 'list' => $servers, + 'enabled' => Dnbd3::isEnabled(), + 'checked_s' => Dnbd3::isEnabled() ? 'checked' : '', + )); } private function showClientList() { $server = $this->getServerById(); Render::addTemplate('page-header-servername', $server); - $data = Dnbd3Rpc::query(false, true, false, $server['ip']); + $data = Dnbd3Rpc::query($server['ip'], 5003,false, true, false, false); if ($data === false || !isset($data['clients'])) { Message::addError('server-unreachable'); return; @@ -226,7 +255,7 @@ class Page_Dnbd3 extends Page $serverId = Request::any('server', false, 'int'); } if ($serverId === false) { - Message::addError('parameter-missing', 'server'); + Message::addError('main.parameter-missing', 'server'); Util::redirect('?do=dnbd3'); } $server = Database::queryFirst('SELECT s.serverid, s.machineuuid, s.fixedip, m.clientip, m.hostname @@ -253,7 +282,7 @@ class Page_Dnbd3 extends Page protected function doAjax() { - $action = Request::post('action', false, 'string'); + $action = Request::any('action', false, 'string'); if ($action === 'servertest') { Header('Content-Type: application/json; charset=utf-8'); $ip = Request::post('ip', false, 'string'); @@ -272,7 +301,7 @@ class Page_Dnbd3 extends Page if ($res !== false) die('{"error": "Server with this IP already exists", "fatal": true}'); // Query - $reply = Dnbd3Rpc::query(true, false, false, $ip); + $reply = Dnbd3Rpc::query($ip, 5003,true, false, false, true); if ($reply === false) die('{"error": "Could not reach server"}'); if (!is_array($reply)) @@ -280,6 +309,16 @@ class Page_Dnbd3 extends Page if (!isset($reply['uptime']) || !isset($reply['clientCount'])) die('{"error": "Reply does not suggest this is a dnbd3 server"}'); echo json_encode($reply); + } elseif ($action === 'editserver') { + $server = $this->getServerById(); + if (isset($server['machineuuid'])) { + echo 'Not automatic server.'; + } else { + //RunMode::getForModule() + echo Render::parse('fragment-server-settings', $server); + } + } else { + die($action . '???'); } } diff --git a/modules-available/dnbd3/templates/page-server-locations.html b/modules-available/dnbd3/templates/page-server-locations.html index 8e76a68d..20dddaac 100644 --- a/modules-available/dnbd3/templates/page-server-locations.html +++ b/modules-available/dnbd3/templates/page-server-locations.html @@ -7,7 +7,7 @@
- diff --git a/modules-available/dnbd3/templates/page-serverlist.html b/modules-available/dnbd3/templates/page-serverlist.html index 76f9ca35..84c587a2 100644 --- a/modules-available/dnbd3/templates/page-serverlist.html +++ b/modules-available/dnbd3/templates/page-serverlist.html @@ -1,128 +1,252 @@

{{lang_dnbd3Management}}

{{lang_dnbd3IntroText}}

-
+
+
+ {{lang_dnbd3Status}}: + + {{#enabled}}{{lang_enabled}}{{/enabled}} + {{^enabled}}{{lang_disabled}} (NFS/CIFS){{/enabled}} + + – {{lang_changeDnbd3Status}} +
+
+
+ + +
+ + +
+ + +
+
+
+ +
+

{{lang_serverList}} - +

+
- - - - - - - - - - - {{#list}} - - - - - - - - - - - {{/list}} + + + + + + + + + + + + + + + + + + {{#list}} + + + + + + + + + + + + + + {{/list}} +
{{lang_proxyServerTHead}}{{lang_clientCount}}{{lang_lastSeen}}{{lang_uptime}}{{lang_txTotal}}{{lang_rxTotal}}{{lang_locations}} 
- {{#uptime}} - - {{/uptime}} - {{^uptime}} - - {{/uptime}} - {{fixedip}} - {{#machineuuid}} - {{clientip}} -
{{hostname}}
- {{/machineuuid}} -
- {{#uptime}} - {{clientcount}} - {{/uptime}} - {{^uptime}} - - - {{/uptime}} - - {{lastseen_s}} - - {{uptime_s}} - - {{totalup_s}} - - {{totaldown_s}} - - {{^self}} - {{^locations}} - {{lang_global}} - {{/locations}} - {{#locations}} - {{locations}} - {{/locations}} - - - - {{/self}} - - {{^self}} - - {{/self}} -
{{lang_proxyServerTHead}}{{lang_storageSize}}{{lang_clientCount}}{{lang_lastSeen}}{{lang_uptime}}{{lang_txTotal}}{{lang_rxTotal}}{{lang_locations}}
+ {{#slxOk}} + + {{/slxOk}} + {{#slxDown}} + + {{/slxDown}} + + {{#uptime}} + + {{/uptime}} + {{^uptime}} + + {{/uptime}} + + {{fixedip}} + {{#machineuuid}} + {{clientip}} +
{{hostname}}
+ {{/machineuuid}} +
+
+ {{disktotal_s}} +
+
+ {{#uptime}} + {{clientcount}} + {{/uptime}} + {{^uptime}} + - + {{/uptime}} + + {{dnbd3lastseen_s}} + + {{uptime_s}} + + {{totalup_s}} + + {{totaldown_s}} + + {{^self}} + {{^locations}} + {{lang_global}} + {{/locations}} + {{#locations}} + {{locations}} + {{/locations}} + + + + {{/self}} + + {{#machineuuid}} + + {{/machineuuid}} + {{^self}} + + {{/self}} +
-
- - - - {{lang_addManagedProxy}} - +
+
+ + +
+
-