From ee80b183d90b6e05e3730813eb76386ff6377e3c Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Fri, 11 Sep 2020 11:05:33 +0200 Subject: #992: New REST route `/ous/:ouid/labs/:labid/clients/:clntid/init` New route to boot up a computer and init session on the operating systems where the image was restored. UDS will request this route when it detects that a reserved computer is turned off. --- admin/WebConsole/rest/remotepc.php | 198 ++++++++++++++++++++++++++++++++----- 1 file changed, 172 insertions(+), 26 deletions(-) diff --git a/admin/WebConsole/rest/remotepc.php b/admin/WebConsole/rest/remotepc.php index e11f8870..428d5252 100644 --- a/admin/WebConsole/rest/remotepc.php +++ b/admin/WebConsole/rest/remotepc.php @@ -39,13 +39,13 @@ $app->post('/ous/:ouid/images/:imageid/reserve(/)', 'validateApiKey', global $ACCION_SINRESULTADO; global $ACCION_FALLIDA; global $userid; - $response = Array(); - $ogagent = Array(); - $repo = Array(); + $response = []; + $ogagent = []; + $repo = []; if ($app->settings['debug']) writeRemotepcLog($app->request()->getResourceUri(). ": Init."); - // Checking parameters. + // Checking parameters. try { if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); @@ -120,35 +120,35 @@ EOD; $repoip = $rs->campos["repoip"]; $repokey = $rs->campos["repokey"]; // Check client's status. - $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status"; + $ogagent = [['url' => "https://$clntip:8000/opengnsys/status"]]; if ($app->settings['debug']) - writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent status, url=".$ogagent[$clntip]['url']."."); + writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent status, url=".$ogagent[0]['url']."."); $result = multiRequest($ogagent); - if (empty($result[$clntip]['data'])) { + if (empty($result[0]['data'])) { // Client is off, send WOL command to ogAdmServer. // TODO: if client is busy????? if ($app->settings['debug']) writeRemotepcLog($app->request()->getResourceUri(). ": Send boot command through ogAdmServer: iph=$clntip,mac=$clntmac."); wol(1, [$clntmac], [$clntip], [$clntnetmask]); // Send WOL command to client repository. - $repo[$repoip]['url'] = "https://$repoip/opengnsys/rest/repository/poweron"; - $repo[$repoip]['header'] = Array("Authorization: ".$repokey); - $repo[$repoip]['post'] = '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}'; + $repo = [['url' => "https://$repoip/opengnsys/rest/repository/poweron", + 'header' => ["Authorization: $repokey"], + 'post' => '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}']]; if ($app->settings['debug']) - writeRemotepcLog($app->request()->getResourceUri(). ": Send Boot command through repo: repo=$repoip, ip=$clntip,mac=$clntmac."); + writeRemotepcLog($app->request()->getResourceUri(). ": Send Boot command through repo: repo=$repoip,ip=$clntip,mac=$clntmac."); $result = multiRequest($repo); // ... (check response) - //if ($result[$repoip]['code'] != 200) { + //if ($result[0]['code'] != 200) { // ... } else { - // Client is on, send a rieboot command to its OGAgent. - $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/reboot"; - $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey); + // Client is on, send a reboot command to its OGAgent. + $ogagent = [['url' => "https://$clntip:8000/opengnsys/reboot", + 'header' => ["Authorization: ".$agentkey]]]; if ($app->settings['debug']) - writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent reboot, url=".$ogagent[$clntip]['url']."."); + writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent reboot, url=".$ogagent[0]['url']."."); $result = multiRequest($ogagent); // ... (check response) - //if ($result[$clntip]['code'] != 200) { + //if ($result[0]['code'] != 200) { // ... } // DB Transaction: mark choosed client as reserved and @@ -265,7 +265,7 @@ $app->post('/ous/:ouid/labs/:labid/clients/:clntid/events', 'validateApiKey', if ($app->settings['debug']) writeRemotepcLog($app->request()->getResourceUri(). ": Init."); - // Checking parameters. + // Checking parameters. try { if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); @@ -359,7 +359,7 @@ $app->post('/ous/:ouid/labs/:labid/clients/:clntid/session', 'validateApiKey', if ($app->settings['debug']) writeRemotepcLog($app->request()->getResourceUri(). ": Init."); - // Checking parameters. + // Checking parameters. try { if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); @@ -463,12 +463,12 @@ $app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey global $cmd; global $userid; global $ACCION_INICIADA; - $response = Array(); - $ogagent = Array(); + $response = []; + $ogagent = []; if ($app->settings['debug']) writeRemotepcLog($app->request()->getResourceUri(). ": Init."); - // Checking parameters. + // Checking parameters. try { if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); @@ -537,13 +537,13 @@ EOD; $cmd->texto = "COMMIT;"; $cmd->Ejecutar(); // Send a poweroff command to client's OGAgent. - $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/poweroff"; - $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey); + $ogagent = [['url' => "https://$clntip:8000/opengnsys/poweroff", + 'header' => ["Authorization: ".$agentkey]]]; if ($app->settings['debug']) - writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent poweroff, url=".$ogagent[$clntip]['url']."."); + writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent poweroff, url=".$ogagent[0]['url']."."); $result = multiRequest($ogagent); // ... (check response) - //if ($result[$clntip]['code'] != 200) { + //if ($result[0]['code'] != 200) { // ... // Confirm operation. $response = ""; @@ -562,3 +562,149 @@ EOD; } ); + +/* + * @brief Send an init operation to a client with an image installed. + * @note Route: /ous/:ouid/labs/:labid/clients/:clntid/init, Method: POST + * @param int image Image id. + */ +$app->post('/ous/:ouid/labs/:labid/clients/:clntid/init', 'validateApiKey', + function($ouid, $labid, $clntid) use ($app) { + global $cmd; + global $userid; + + if ($app->settings['debug']) + writeRemotepcLog("{$app->request()->getResourceUri()}: Init."); + // Checking parameters. + try { + if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { + throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); + } + if (!checkIds($ouid, $labid, $clntid)) { + throw new Exception("Ids. must be positive integers"); + } + // Reading POST parameters in JSON format. + $input = json_decode($app->request()->getBody()); + $imageid = $input->image ?? 0; + if (filter_var($imageid, FILTER_VALIDATE_INT, $opts) === false) { + throw new Exception("Image id. must be positive integer"); + } + } catch (Exception $e) { + // Communication error. + $response["message"] = $e->getMessage(); + if ($app->settings['debug']) + writeRemotepcLog("{$app->request()->getResourceUri()}: ERROR: {$response["message"]}."); + jsonResponse(400, $response); + $app->stop(); + } + + // Select data to init a session. + $cmd->texto = <<Comando=&$cmd; + if (!$rs->Abrir()) return(false); // Error opening recordset. + // Check if user is admin and client exists. + $rs->Primero(); + if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) { + // Read query data. + $clntip = $rs->campos["ip"]; + $clntmac = $rs->campos["mac"]; + $clntnetmask = $rs->campos["mascara"]; + $agentkey = $rs->campos["agentkey"]; + $disk = $rs->campos["numdisk"]; + $part = $rs->campos["numpar"]; + $repoip = $rs->campos["repoip"]; + $repokey = $rs->campos["repokey"]; + // Check client's status. + $ogagent = [['url' => "https://$clntip:8000/opengnsys/status"]]; + if ($app->settings['debug']) + writeRemotepcLog("{$app->request()->getResourceUri()}: OGAgent status, url={$ogagent[0]['url']}."); + $result = multiRequest($ogagent); + if (empty($result[0]['data'])) { + // Client is off, send WOL command to ogAdmServer. + // TODO: if client is busy????? + if ($app->settings['debug']) + writeRemotepcLog("{$app->request()->getResourceUri()}: Send boot command through ogAdmServer: iph=$clntip,mac=$clntmac."); + wol(1, [$clntmac], [$clntip], [$clntnetmask]); + // Send WOL command to client repository. + $repo = [['url' => "https://$repoip/opengnsys/rest/repository/poweron", + 'header' => ["Authorization: $repokey"], + 'post' => '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}']]; + if ($app->settings['debug']) + writeRemotepcLog("{$app->request()->getResourceUri()}: Send Boot command through repo: repo=$repoip,ip=$clntip,mac=$clntmac."); + $result = multiRequest($repo); + } + // Create an init session on opertions queue. + $cmd->texto = <<Ejecutar(); + // Create event to remove the operation on timeout (15 min.). + $timeout = "15 MINUTE"; + $cmd->texto = <<Ejecutar(); + if ($app->settings['debug']) + writeRemotepcLog("{$app->request()->getResourceUri()}: DB tables and events updated, clntid=$clntid."); + // Send init session command if client is booted on ogLive. + if ($app->settings['debug']) + writeRemotepcLog("{$app->request()->getResourceUri()}: Send Init Session command to ogAdmClient, ido=$clntid,iph=$clntip,dsk=$disk,par=$part."); + session($clntip, "$disk\r$part"); + // Confirm operation. + $response = []; + jsonResponse(200, $response); + } else { + // Error message. + $response["message"] = "Client with this image not found"; + jsonResponse(404, $response); + } + $rs->Cerrar(); + } +); + -- cgit v1.2.3-18-g5258