source: admin/WebConsole/rest/remotepc.php @ 5827bb9

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacionwebconsole3
Last change on this file since 5827bb9 was d8b6c70, checked in by ramon <ramongomez@…>, 8 years ago

#708: Establecer tiempo máximo de reserva para que un equipo pueda ser usado en acceso remoto.

git-svn-id: https://opengnsys.es/svn/branches/version1.1@5275 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100644
File size: 12.0 KB
Line 
1<?php
2/**
3 * @file    remotepc.php
4 * @brief   OpenGnsys Server REST API consumed by UDS Server for Remote PC implementation.
5 * @warning All input and output messages are formatted in JSON.
6 * @note    Some ideas are based on article "How to create REST API for Android app using PHP, Slim and MySQL" by Ravi Tamada, thanx.
7 * @license GNU GPLv3+
8 * @author  Ramón M. Gómez, ETSII Univ. Sevilla
9 * @version 1.1.0 - First version
10 * @date    2017-02-01
11 */
12
13
14// REST routes.
15
16/**
17 * @brief    Reserve a random client with an installed image and send a boot/reboot operation depending on its status.
18 * @warning  If "lab" parameter is specified, then choose a client from this lab.
19 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST
20 * @param    integer ouid      OU identificator
21 * @param    integer imageid   image identificator
22 * @param    integer labid     lab. identificator (optional)
23 */
24$app->post('/ous/:ouid/images/:imageid/reserve(/)', 'validateApiKey',
25    function($ouid, $imageid) use ($app) {
26        global $cmd;
27        global $AMBITO_ORDENADORES;
28        global $EJECUCION_COMANDO;
29        global $ACCION_INICIADA;
30        global $ACCION_SINRESULTADO;
31        global $userid;
32        $response = Array();
33        $ogagent = Array();
34
35        // Checking parameters.
36        try {
37                if (!check_ids($ouid, $imageid)) {
38                        throw new Exception("Ids. must be positive integers");
39                }
40                // Reading POST parameters in JSON format.
41                $input = json_decode($app->request()->getBody());
42                $labid = isset($input->labid) ? $input->labid : '%';    // Default: no lab. filter
43                $maxtime = isset($input->maxtime) ? $input->maxtime : 24;       // Default: 24 h.
44                if (!filter_var($labid, FILTER_VALIDATE_INT, $opts) and $labid !== '%') {
45                        throw new Exception("Lab id. must be positive integer");
46                }
47                if (!filter_var($maxtime, FILTER_VALIDATE_INT, $opts)) {
48                        throw new Exception("Time must be positive integer (in hours)");
49                }
50        } catch (Exception $e) {
51                // Communication error.
52                $response["message"] = $e->getMessage();
53                jsonResponse(400, $response);
54                $app->stop();
55        }
56        // Randomly choose a client with image installed and get ogAdmServer data.
57        $cmd->texto = <<<EOD
58SELECT adm.idadministradorcentro, entornos.ipserveradm, entornos.portserveradm,
59       ordenadores.idordenador, ordenadores.nombreordenador, ordenadores.ip,
60       ordenadores.mac, ordenadores.agentkey, ordenadores_particiones.numdisk,
61       ordenadores_particiones.numpar, aulas.idaula, aulas.idcentro,
62       remotepc.reserved
63  FROM entornos, ordenadores
64  JOIN aulas USING(idaula)
65 RIGHT JOIN administradores_centros AS adm USING(idcentro)
66 RIGHT JOIN usuarios USING(idusuario)
67 RIGHT JOIN ordenadores_particiones USING(idordenador)
68 RIGHT JOIN imagenes USING(idimagen)
69  LEFT JOIN remotepc ON remotepc.id=ordenadores.idordenador
70 WHERE adm.idadministradorcentro = '$userid'
71   AND aulas.idcentro = '$ouid' AND aulas.idaula LIKE '$labid' AND aulas.inremotepc = 1
72   AND imagenes.idimagen = '$imageid' AND imagenes.inremotepc = 1
73 ORDER BY RAND() LIMIT 1;
74EOD;
75        $rs=new Recordset;
76        $rs->Comando=&$cmd;
77        if (!$rs->Abrir()) return(false);       // Error opening recordset.
78        // Check if user is admin and client exists.
79        $rs->Primero();
80        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
81                // Check if client is not reserved.
82                if (is_null($rs->campos["reserved"])) {
83                        // Read query data.
84                        $serverip = $rs->campos["ipserveradm"];
85                        $serverport = $rs->campos["portserveradm"];
86                        $clntid = $rs->campos["idordenador"];
87                        $clntname = $rs->campos["name"];
88                        $clntip = $rs->campos["ip"];
89                        $clntmac = $rs->campos["mac"];
90                        $agentkey = $rs->campos["agentkey"];
91                        $disk = $rs->campos["numdisk"];
92                        $part = $rs->campos["numpar"];
93                        $labid = $rs->campos["idaula"];
94                        $ouid = $rs->campos["idcentro"];
95                        // Check client's status.
96                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status";
97                        $result = multiRequest($ogagent);
98                        if (empty($result[$clntip]['data'])) {
99                                // Client is off, send a boot command to ogAdmServer.
100                                $reqframe = "nfn=Arrancar\r".
101                                            "ido=$clntid\r".
102                                            "iph=$clntip\r".
103                                            "mac=$clntmac\r".
104                                            "mar=1\r";
105                                sendCommand($serverip, $serverport, $reqframe, $values);
106                        } else {
107                                // Client is on, send a reboot command to its OGAgent.
108                                $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/reboot";
109                                $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
110                                $result = multiRequest($ogagent);
111                                // ... (check response)
112                                //if ($result[$clntip]['code'] != 200) {
113                                // ...
114                        }
115                        // DB Transaction: mark choosed client as reserved and
116                        // create an init session command into client's actions queue.
117                        $cmd->texto = "START TRANSACTION;";
118                        $cmd->Ejecutar();
119                        $timestamp = time();
120                        $cmd->texto = <<<EOD
121INSERT INTO remotepc
122   SET id='$clntid', reserved=NOW() + INTERVAL $maxtime HOUR, urllogin=NULL, urllogout=NULL
123    ON DUPLICATE KEY UPDATE
124       id=VALUES(id), reserved=VALUES(reserved),
125       urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
126EOD;
127                        $t1 = $cmd->Ejecutar();
128                        $cmd->texto = <<<EOD
129INSERT INTO acciones
130   SET tipoaccion=$EJECUCION_COMANDO,
131       idtipoaccion=9,
132       idcomando=9,
133       parametros='nfn=IniciarSesion\rdsk=$disk\rpar=$part',
134       descriaccion='RemotePC Session',
135       idordenador=$clntid,
136       ip='$clntip',
137       sesion=$timestamp,
138       fechahorareg=NOW(),
139       estado=$ACCION_INICIADA,
140       resultado=$ACCION_SINRESULTADO,
141       ambito=$AMBITO_ORDENADORES,
142       idambito=$clntid,
143       restrambito='$clntip',
144       idcentro=$ouid;
145EOD;
146                        $t2 = $cmd->Ejecutar();
147                        if ($t1 and $t2) {
148                                // Commit transaction on success.
149                                $cmd->texto = "COMMIT;";
150                                $cmd->Ejecutar();
151                                // Send init session command if client is booted on ogLive.
152                                $reqframe = "nfn=IniciarSesion\r".
153                                        "ido=$clntid\r".
154                                            "iph=$clntip\r".
155                                            "dsk=$disk\r".
156                                            "par=$part\r";
157                                sendCommand($serverip, $serverport, $reqframe, $values);
158                                // Compose JSON response.
159                                $response['id'] = $clntid;
160                                $response['name'] = $clntname;
161                                $response['ip'] = $clntip;
162                                $response['mac'] = $clntmac;
163                                $response['lab']['id'] = $labid;
164                                $response['ou']['id'] = $ouid;
165                                jsonResponse(200, $response);
166                        } else{
167                                // Roll-back transaction on DB error.
168                                $cmd->texto = "ROLLBACK;";
169                                $cmd->Ejecutar();
170                                // Error message.
171                                $response["message"] = "Database error";
172                                jsonResponse(400, $response);
173                                $app->stop();
174                        }
175                } else {
176                        // Error message.
177                        $response["message"] = "Client is already reserved";
178                        jsonResponse(400, $response);
179                        $app->stop();
180                }
181        }
182        $rs->Cerrar();
183    }
184);
185
186
187/**
188 * @brief    Store UDS server URLs to resend some events recieved from OGAgent.
189 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST
190 * @param    string urlLogin   URL to redirect login notification.
191 * @param    string urlLogout  URL to redirect logout notification.
192 * @warning  Events parameters will be stored in a new "remotepc" table.
193 */
194$app->post('/ous/:ouid/labs/:labid/clients/:clntid/events', 'validateApiKey',
195    function($ouid, $labid, $clntid) use ($app) {
196        global $cmd;
197        global $userid;
198        $response = Array();
199
200        // Checking parameters.
201        try {
202                if (!check_ids($ouid, $labid, $clntid)) {
203                        throw new Exception("Ids. must be positive integers");
204                }
205                // Reading JSON parameters.
206                $input = json_decode($app->request()->getBody());
207                $urlLogin = htmlspecialchars($input->urlLogin);
208                $urlLogout = htmlspecialchars($input->urlLogout);
209                if (!filter_var($urlLogin, FILTER_VALIDATE_URL)) {
210                        throw new Exception("Must be a valid URL for login notification");
211                }
212                if (!filter_var($urlLogout, FILTER_VALIDATE_URL)) {
213                        throw new Exception("Must be a valid URL for logout notification");
214                }
215        } catch (Exception $e) {
216                // Error message.
217                $response["message"] = $e->getMessage();
218                jsonResponse(400, $response);
219                $app->stop();
220        }
221
222        // Select client data for UDS compatibility.
223        $cmd->texto = <<<EOD
224SELECT adm.idadministradorcentro, ordenadores.idordenador, remotepc.*
225  FROM remotepc
226 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
227  JOIN aulas USING(idaula)
228 RIGHT JOIN administradores_centros AS adm USING(idcentro)
229 RIGHT JOIN usuarios USING(idusuario)
230 WHERE adm.idadministradorcentro = '$userid'
231   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
232   AND ordenadores.idordenador = '$clntid';
233EOD;
234        $rs=new Recordset;
235        $rs->Comando=&$cmd;
236        if (!$rs->Abrir()) return(false);       // Error opening recordset.
237        // Check if user is admin and client exists.
238        $rs->Primero();
239        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
240                // Check if client is reserved.
241                if (! is_null($rs->campos["reserved"])) {
242                        // Updating DB if client is reserved.
243                        $cmd->CreaParametro("@urllogin", $urlLogin, 0);
244                        $cmd->CreaParametro("@urllogout", $urlLogout, 0);
245                        $cmd->texto = <<<EOD
246INSERT INTO remotepc
247   SET id='$clntid', urllogin=@urllogin, urllogout=@urllogout
248    ON DUPLICATE KEY UPDATE
249       id=VALUES(id), urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
250EOD;
251                        if ($cmd->Ejecutar()) {
252                                // Confirm operation.
253                                jsonResponse(200, "");
254                        } else {
255                                // Error message.
256                                $response["message"] = "Database error";
257                                jsonResponse(400, $response);
258                                $app->stop();
259                        }
260                } else {
261                        // Error message.
262                        $response["message"] = "Client is not reserved";
263                        jsonResponse(400, $response);
264                        $app->stop();
265                }
266        }
267        $rs->Cerrar();
268    }
269);
270
271
272$app->post('/ous/:ouid/labs/:labid/clients/:clntid/session', 'validateApiKey',
273    function($ouid, $imageid) use ($app) {
274    }
275);
276
277
278$app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey',
279    function($ouid, $labid, $clntid) {
280        global $cmd;
281        global $userid;
282        global $ACCION_INICIADA;
283        $response = Array();
284        $ogagent = Array();
285
286        // Checking parameters.
287        try {
288                if (!check_ids($ouid, $labid, $clntid)) {
289                        throw new Exception("Ids. must be positive integers");
290                }
291        } catch (Exception $e) {
292                // Error message.
293                $response["message"] = $e->getMessage();
294                jsonResponse(400, $response);
295                $app->stop();
296        }
297
298        // Select client data for UDS compatibility.
299        $cmd->texto = <<<EOD
300SELECT adm.idadministradorcentro, ordenadores.idordenador, ordenadores.ip, ordenadores.agentkey, remotepc.reserved
301  FROM remotepc
302 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
303  JOIN aulas USING(idaula)
304 RIGHT JOIN administradores_centros AS adm USING(idcentro)
305 RIGHT JOIN usuarios USING(idusuario)
306 WHERE adm.idadministradorcentro = '$userid'
307   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
308   AND ordenadores.idordenador = '$clntid';
309EOD;
310        $rs=new Recordset;
311        $rs->Comando=&$cmd;
312        if (!$rs->Abrir()) return(false);       // Error opening recordset.
313        // Check if user is admin and client exists.
314        $rs->Primero();
315        if (checkAdmin($rs->campos["idadministradorcentro"]) and checkParameter($rs->campos["idordenador"])) {
316                // Check if client is reserved.
317                if (! is_null($rs->campos["reserved"])) {
318                        // Read query data.
319                        $clntip = $rs->campos["ip"];
320                        $agentkey = $rs->campos["agentkey"];
321                        // DB Transaction: clear client reservation data and
322                        // remove pending boot commands from client's actions queue.
323                        $cmd->texto = "START TRANSACTION;";
324                        $cmd->Ejecutar();
325                        $cmd->texto = <<<EOD
326UPDATE remotepc
327   SET reserved=NULL, urllogin=NULL, urllogout=NULL
328 WHERE id='$clntid';
329EOD;
330                        $cmd->Ejecutar();
331                        $cmd->texto = <<<EOD
332DELETE FROM acciones
333 WHERE idordenador = '$clntid'
334   AND descriaccion = 'RemotePC Session'
335   AND estado = $ACCION_INICIADA;
336EOD;
337                        $cmd->Ejecutar();
338                        $cmd->texto = "COMMIT;";
339                        $cmd->Ejecutar();
340                        // Send a poweroff command to client's OGAgent.
341                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/poweroff";
342                        $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
343                        $result = multiRequest($ogagent);
344                        // ... (check response)
345                        //if ($result[$clntip]['code'] != 200) {
346                        // ...
347                        // Confirm operation.
348                        jsonResponse(200, "");
349                } else {
350                        // Error message.
351                        $response["message"] = "Client is not reserved";
352                        jsonResponse(400, $response);
353                }
354        }
355        $rs->Cerrar();
356    }
357);
358
359?>
Note: See TracBrowser for help on using the repository browser.