post('/ous/:ouid/images/:imageid/reserve(/)', 'validateApiKey', function($ouid, $imageid) use ($app) { global $cmd; global $AMBITO_ORDENADORES; global $EJECUCION_COMANDO; global $ACCION_INICIADA; global $ACCION_FINALIZADA; global $ACCION_SINRESULTADO; global $ACCION_FALLIDA; global $userid; $response = Array(); $ogagent = Array(); // Checking parameters. try { if (!checkIds($ouid, $imageid)) { throw new Exception("Ids. must be positive integers"); } // Reading POST parameters in JSON format. $input = json_decode($app->request()->getBody()); // Default: no lab. filter. if (isset($input->labid)) { $labid = $input->labid != "0" ? $input->labid : '%'; } else { $labid = '%'; } $maxtime = isset($input->maxtime) ? $input->maxtime : 24; // Default: 24 h. $opts = Array('options' => Array('min_range' => 1)); // Check for int>0 if (!filter_var($labid, FILTER_VALIDATE_INT, $opts) and $labid !== '%') { throw new Exception("Lab id. must be positive integer"); } if (!filter_var($maxtime, FILTER_VALIDATE_INT, $opts)) { throw new Exception("Time must be positive integer (in hours)"); } // Check for a valid remote agent. if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); } } catch (Exception $e) { // Communication error. $response["message"] = $e->getMessage(); jsonResponse(400, $response); $app->stop(); } // Choose older not-reserved client with image installed and get ogAdmServer data. $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["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) { // Read query data. $serverip = $rs->campos["ipserveradm"]; $serverport = $rs->campos["portserveradm"]; $clntid = $rs->campos["idordenador"]; $clntname = $rs->campos["nombreordenador"]; $clntip = $rs->campos["ip"]; $clntmac = $rs->campos["mac"]; $agentkey = $rs->campos["agentkey"]; $disk = $rs->campos["numdisk"]; $part = $rs->campos["numpar"]; $labid = $rs->campos["idaula"]; $ouid = $rs->campos["idcentro"]; // Check client's status. $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status"; $result = multiRequest($ogagent); if (empty($result[$clntip]['data'])) { // Client is off, send a boot command to ogAdmServer. // TODO: if client is busy????? $reqframe = "nfn=Arrancar\r". "ido=$clntid\r". "iph=$clntip\r". "mac=$clntmac\r". "mar=1\r"; sendCommand($serverip, $serverport, $reqframe, $values); } else { // Client is on, send a reboot command to its OGAgent. $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/reboot"; $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey); $result = multiRequest($ogagent); // ... (check response) //if ($result[$clntip]['code'] != 200) { // ... } // DB Transaction: mark choosed client as reserved and // create an init session command into client's actions queue. $cmd->texto = "START TRANSACTION;"; $cmd->Ejecutar(); $timestamp = time(); $cmd->texto = <<Ejecutar(); $cmd->texto = <<Ejecutar(); // Create event to remove reservation on timeout (15 min.). $timeout = "15 MINUTE"; $cmd->texto = <<Ejecutar(); if ($t1 and $t2 and $t3) { // Commit transaction on success. $cmd->texto = "COMMIT;"; $cmd->Ejecutar(); // Send init session command if client is booted on ogLive. $reqframe = "nfn=IniciarSesion\r". "ido=$clntid\r". "iph=$clntip\r". "dsk=$disk\r". "par=$part\r"; sendCommand($serverip, $serverport, $reqframe, $values); // Compose JSON response. $response['id'] = $clntid; $response['name'] = $clntname; $response['ip'] = $clntip; $response['mac'] = $clntmac; $response['lab']['id'] = $labid; $response['ou']['id'] = $ouid; jsonResponse(200, $response); } else { // Roll-back transaction on DB error. $cmd->texto = "ROLLBACK;"; $cmd->Ejecutar(); // Error message. $response["message"] = "Database error"; jsonResponse(400, $response); $app->stop(); } } $rs->Cerrar(); } ); /** * @brief Store UDS server URLs to resend some events recieved from OGAgent. * @note Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST * @param string urlLogin URL to redirect login notification. * @param string urlLogout URL to redirect logout notification. * @warning Events parameters will be stored in a new "remotepc" table. */ $app->post('/ous/:ouid/labs/:labid/clients/:clntid/events', 'validateApiKey', function($ouid, $labid, $clntid) use ($app) { global $cmd; global $userid; $response = Array(); // Checking parameters. try { if (!checkIds($ouid, $labid, $clntid)) { throw new Exception("Ids. must be positive integers"); } // Reading JSON parameters. $input = json_decode($app->request()->getBody()); $urlLogin = htmlspecialchars($input->urlLogin); $urlLogout = htmlspecialchars($input->urlLogout); if (!filter_var($urlLogin, FILTER_VALIDATE_URL)) { throw new Exception("Must be a valid URL for login notification"); } if (!filter_var($urlLogout, FILTER_VALIDATE_URL)) { throw new Exception("Must be a valid URL for logout notification"); } // Check for a valid remote agent. if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); } } catch (Exception $e) { // Error message. $response["message"] = $e->getMessage(); jsonResponse(400, $response); $app->stop(); } // Select client data for UDS compatibility. $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["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) { // Check if client is reserved. if (! is_null($rs->campos["reserved"])) { // Updating DB if client is reserved. $cmd->CreaParametro("@urllogin", $urlLogin, 0); $cmd->CreaParametro("@urllogout", $urlLogout, 0); $cmd->texto = <<Ejecutar()) { // Confirm operation. jsonResponse(200, ""); } else { // Error message. $response["message"] = "Database error"; jsonResponse(400, $response); $app->stop(); } } else { // Error message. $response["message"] = "Client is not reserved"; jsonResponse(400, $response); $app->stop(); } } $rs->Cerrar(); } ); $app->post('/ous/:ouid/labs/:labid/clients/:clntid/session', 'validateApiKey', function($ouid, $imageid) use ($app) { } ); $app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey', function($ouid, $labid, $clntid) { global $cmd; global $userid; global $ACCION_INICIADA; $response = Array(); $ogagent = Array(); // Checking parameters. try { if (!checkIds($ouid, $labid, $clntid)) { throw new Exception("Ids. must be positive integers"); } // Check for a valid remote agent. if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) { throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']); } } catch (Exception $e) { // Error message. $response["message"] = $e->getMessage(); jsonResponse(400, $response); $app->stop(); } // Select client data for UDS compatibility. $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["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) { // Check if client is reserved. if (! is_null($rs->campos["reserved"])) { // Read query data. $clntip = $rs->campos["ip"]; $agentkey = $rs->campos["agentkey"]; // DB Transaction: set reservation time to the past and // remove pending boot commands from client's actions queue. $cmd->texto = "START TRANSACTION;"; $cmd->Ejecutar(); $cmd->texto = <<Ejecutar(); $cmd->texto = <<Ejecutar(); $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); $result = multiRequest($ogagent); // ... (check response) //if ($result[$clntip]['code'] != 200) { // ... // Confirm operation. jsonResponse(200, ""); } else { // Error message. $response["message"] = "Client is not reserved"; jsonResponse(400, $response); } } $rs->Cerrar(); } ); ?>