source: admin/WebConsole/rest/server.php @ a51c727

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 a51c727 was 146d955, checked in by ramon <ramongomez@…>, 9 years ago

#708: Añadir algunos campos en rutas REST; docmentar ruta /ous/:ouid/groups y repasar definciones de seguridad y de campos requeridos.

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

  • Property mode set to 100644
File size: 32.2 KB
Line 
1<?php
2/**
3 * @file    index.php
4 * @brief   OpenGnsys REST API manager.
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 - Primera versión para OpenGnsys
10 * @date    2016-09-19
11 */
12
13
14// Auxiliar functions.
15
16/**
17 * @brief   Compose JSON response.
18 * @param   int status      Status code for HTTP response.
19 * @param   array response  Response data.
20 * @return  string          JSON response.
21 */
22function jsonResponse($status, $response) {
23        $app = \Slim\Slim::getInstance();
24        // HTTP status code.
25        $app->status($status);
26        // Content-type HTTP header.
27        $app->contentType('application/json');
28        // JSON response.
29        echo json_encode($response);
30}
31
32/**
33 * @brief    Validate API key included in "Authorization" HTTP header.
34 * @return   JSON response on error.
35 */
36function validateApiKey() {
37        global $cmd;
38        global $userid;
39        $response = array();
40
41        // Read Authorization HTTP header.
42        $headers = apache_request_headers();
43        if (! empty($headers['Authorization'])) {
44                // Assign user id. that match this key to global variable.
45                $apikey = htmlspecialchars($headers['Authorization']);
46                $cmd->texto = "SELECT idusuario
47                                 FROM usuarios
48                                WHERE apikey='$apikey'";
49                $rs=new Recordset;
50                $rs->Comando=&$cmd;
51                if ($rs->Abrir()) {
52                        $rs->Primero();
53                        if (!$rs->EOF){
54                                // Fetch user id.
55                                $userid = $rs->campos["idusuario"];
56                        } else {
57                                // Credentials error.
58                                $response['message'] = 'Login failed. Incorrect credentials';
59                                jsonResponse(401, $response);
60                                $app->stop();
61                        }
62                        $rs->Cerrar();
63                } else {
64                        // Access error.
65                        $response['message'] = "An error occurred, please try again";
66                        jsonResponse(500, $response);
67                }
68        } else {
69                // Error: missing API key.
70                $response['message'] = 'Missing API key';
71                jsonResponse(400, $response);
72                $app->stop();
73        }
74}
75
76/**
77 * @brief    Check if parameter is set and print error messages if empty.
78 * @param    string param    Parameter to check.
79 * @return   boolean         "false" if parameter is null, otherwise "true".
80 */
81function checkParameter($param) {
82        if (isset($param)) {
83                return true;
84        } else {
85                // Print error message.
86                $response['message'] = 'Parameter not found';
87                jsonResponse(400, $response);
88                return false;
89        }
90}
91
92/**
93 * @brief    Check if user is administrator and print error messages if not.
94 * @param    int adminid   Administrator id.
95 * @return   boolean       "true" if admin id. is equals to global user id., otherwise "false".
96 */
97function checkAdmin($adminid) {
98        global $userid;
99
100        if ($adminid == $userid) {
101                return true;
102        } else {
103                // Print error message.
104                $response['message'] = 'Cannot access this resource';
105                jsonResponse(401, $response);
106                return false;
107        }
108}
109
110
111/**
112 * @fn       sendCommand($serverip, $serverport, $reqframe, &$values)
113 * @brief    Send a command to an OpenGnsys ogAdmServer and get request.
114 * @param    string serverip    Server IP address.
115 * @param    string serverport  Server port.
116 * @param    string reqframe    Request frame (field's separator is "\r").
117 * @param    array values       Response values (out parameter).
118 * @return   boolean            "true" if success, otherwise "false".
119 */
120function sendCommand($serverip, $serverport, $reqframe, &$values) {
121        global $LONCABECERA;
122        global $LONHEXPRM;
123
124        // Connect to server.
125        $respvalues = "";
126        $connect = new SockHidra($serverip, $serverport);
127        if ($connect->conectar()) {
128                // Send request frame to server.
129                $result = $connect->envia_peticion($reqframe);
130                if ($result) {
131                        // Parse request frame.
132                        $respframe = $connect->recibe_respuesta();
133                        $connect->desconectar();
134                        $paramlen = hexdec(substr($respframe, $LONCABECERA, $LONHEXPRM));
135                        $params = substr($respframe, $LONCABECERA+$LONHEXPRM, $paramlen);
136                        // Fetch values and return result.
137                        $values = extrae_parametros($params, "\r", '=');
138                        return ($values);
139                } else {
140                        // Return with error.
141                        return (false);
142                }
143        } else {
144                // Return with error.
145                return (false);
146        }
147}
148
149// Define REST routes.
150
151/**
152 * @brief    user login.
153 * @note     Route: /login, Method: POST
154 * @param    string username   User name.
155 * @param    string password   User password.
156 * @return   string            JSON response with user id. and API key.
157 * @note     User's API key is stored in a new field of "usuarios" table.
158 */
159$app->post('/login',
160    function() use ($app) {
161        global $cmd;
162        global $userid;
163
164        $response = array();
165
166        // Reading JSON parameters.
167        try {
168                $input = json_decode($app->request()->getBody());
169                $user = htmlspecialchars($input->username);
170                $pass = htmlspecialchars($input->password);
171        } catch (Exception $e) {
172                // Error message.
173                $response["message"] = $e->getMessage();
174                jsonResponse(400, $response);
175                $app->stop();
176        }
177
178        // Check parameters.
179        if (! empty($user) and ! empty($pass)) {
180                // Database query.
181                $cmd->texto = "SELECT idusuario, apikey
182                                 FROM usuarios
183                                WHERE usuario='$user' AND pasguor='$pass'";
184                $rs=new Recordset;
185                $rs->Comando=&$cmd;
186                if ($rs->Abrir()) {
187                        $rs->Primero();
188                        if (!$rs->EOF){
189                                // JSON response.
190                                $userid=$rs->campos["idusuario"];
191                                $apikey=$rs->campos["apikey"];
192                                $response['userid'] = $userid;
193                                $response['apikey'] = $apikey;
194                                jsonResponse(200, $response);
195                        } else {
196                                // Credentials error.
197                                $response['message'] = 'Login failed. Incorrect credentials';
198                                jsonResponse(401, $response);
199                                $app->stop();
200                        }
201                        $rs->Cerrar();
202                } else {
203                        // Access error.
204                        $response['message'] = "An error occurred. Please try again";
205                        jsonResponse(500, $response);
206                        $app->stop();
207                }
208        } else {
209                # Error: missing some input parameter.
210                $response['message'] = 'Missing username or password';
211                jsonResponse(400, $response);
212                $app->stop();
213        }
214    }
215);
216
217/**
218 * @brief    Get the server status
219 * @note     Route: /status, Method: GET
220 * @param    no
221 * @return   JSON array with all data collected from server status. (RAM, %CPU,etc..)
222 */
223$app->get('/status', function() {
224      exec("awk '$1~/Mem/ {print $2}' /proc/meminfo",$memInfo);
225      $memInfo = array("total" => $memInfo[0], "used" => $memInfo[1]);
226      $cpuInfo = exec("awk '$1==\"cpu\" {printf \"%.2f\",($2+$4)*100/($2+$4+$5)}' /proc/stat");
227      $cpuModel = exec("awk -F: '$1~/model name/ {print $2}' /proc/cpuinfo");
228      $response["memInfo"] = $memInfo;
229      $response["cpu"] = array("model" => trim($cpuModel), "usage" => $cpuInfo);
230      jsonResponse(200, $response);
231}
232);
233
234/**
235 * @brief    List all defined Organizational Units
236 * @note     Route: /ous, Method: GET
237 * @param    no
238 * @return   JSON array with id. and name for every defined OU
239 */
240$app->get('/ous', function() {
241        global $cmd;
242
243        $cmd->texto = "SELECT * FROM centros";
244        $rs=new Recordset;
245        $rs->Comando=&$cmd;
246        if (!$rs->Abrir()) return(false); // Error al abrir recordset
247        $response = array();
248        $rs->Primero();
249        while (!$rs->EOF) {
250                $tmp = array();
251                $tmp['id'] = $rs->campos["idcentro"];
252                $tmp['name'] = $rs->campos["nombrecentro"];
253                array_push($response, $tmp);
254                $rs->Siguiente();
255        }
256        $rs->Cerrar();
257        jsonResponse(200, $response);
258}
259);
260
261/**
262 * @brief    Get Organizational Unit data
263 * @note     Route: /ous/id, Method: GET
264 * @param    id      OU id.
265 * @return   JSON string with OU's parameters
266 */
267$app->get('/ous/:ouid', 'validateApiKey',
268    function($ouid) {
269        global $cmd;
270
271        $ouid = htmlspecialchars($ouid);
272        $cmd->texto = "SELECT * FROM centros WHERE idcentro='$ouid';";
273        $rs=new Recordset;
274        $rs->Comando=&$cmd;
275        if (!$rs->Abrir()) return(false); // Error al abrir recordset
276        $rs->Primero();
277        if (checkParameter($rs->campos["nombrecentro"])) {
278                $response['id'] = $ouid;
279                $response['name'] = $rs->campos["nombrecentro"];
280                $response['description'] = $rs->campos["comentarios"];
281                jsonResponse(200, $response);
282        }
283        $rs->Cerrar();
284    }
285);
286
287// Listar grupos.
288$app->get('/ous/:ouid/groups', 'validateApiKey', function($ouid) {
289        global $cmd;
290        global $userid;
291
292        $ouid = htmlspecialchars($ouid);
293        if(checkAdmin($userid, $ouid) == true){
294                // Listar las salas de la UO si el usuario de la apikey es su admin.
295                // Consulta temporal,
296                $cmd->texto = "SELECT * FROM grupos WHERE idcentro='$ouid';";
297                $rs=new Recordset;
298                $rs->Comando=&$cmd;
299                if (!$rs->Abrir()) return(false); // Error al abrir recordset
300                        $rs->Primero();
301                        // Comprobar que exista la UO.
302                        if (checkParameter($rs->campos["idcentro"])) {
303                                $response = array();
304                                while (!$rs->EOF) {
305                                        $tmp = array();
306                                        $tmp['id'] = $rs->campos["idgrupo"];
307                                        $tmp['name'] = $rs->campos["nombregrupo"];
308                                        $tmp['type'] = $rs->campos["tipo"];
309                                        $tmp['comments'] = $rs->campos["comentarios"];
310                                if($rs->campos["grupoid"] != 0){
311                                        $tmp['parent']['id'] = $rs->campos["grupoid"];
312                                }
313                                array_push($response, $tmp);
314                                $rs->Siguiente();
315                        }
316                        jsonResponse(200, $response);
317                }
318                $rs->Cerrar();
319        }
320    }
321);
322
323/**
324 * @brief    List all labs defined in an OU
325 * @note     Route: /ous/id/labs, Method: GET
326 * @param    id      OU id.
327 * @return   JSON string with all UO's labs parameters
328 */
329$app->get('/ous/:ouid/labs', 'validateApiKey',
330    function($ouid) {
331        global $cmd;
332
333        $ouid = htmlspecialchars($ouid);
334        // Listar las salas de la UO si el usuario de la apikey es su admin.
335        $cmd->texto = <<<EOD
336SELECT aulas.*, adm.idadministradorcentro
337  FROM aulas
338 RIGHT JOIN administradores_centros AS adm USING(idcentro)
339 RIGHT JOIN usuarios USING(idusuario)
340 WHERE idcentro='$ouid';
341EOD;
342        $rs=new Recordset;
343        $rs->Comando=&$cmd;
344        if (!$rs->Abrir()) return(false);       // Error al abrir recordset
345        // Comprobar que exista la UO y que el usuario sea su administrador.
346        $rs->Primero();
347        if (checkParameter($rs->campos["idcentro"]) and checkAdmin($rs->campos["idadministradorcentro"])) {
348                $response = array();
349                while (!$rs->EOF) {
350                        $tmp = array();
351                        $tmp['id'] = $rs->campos["idaula"];
352                        $tmp['name'] = $rs->campos["nombreaula"];
353                        $tmp['inremotepc'] = $rs->campos["inremotepc"]==0 ? false: true;
354                        $tmp['group']['id'] = $rs->campos["grupoid"];
355                        $tmp['ou']['id'] = $ouid;
356                        array_push($response, $tmp);
357                        $rs->Siguiente();
358                }
359                jsonResponse(200, $response);
360        }
361        $rs->Cerrar();
362    }
363);
364
365/**
366 * @brief    Get lab data
367 * @note     Route: /ous/id1/labs/id2, Method: GET
368 * @param    id1     OU id.
369 * @param    id2     lab id.
370 * @return   JSON string with lab parameters
371 */
372$app->get('/ous/:ouid/labs/:labid', 'validateApiKey',
373    function($ouid, $labid) {
374        global $cmd;
375
376        $ouid = htmlspecialchars($ouid);
377        $labid = htmlspecialchars($labid);
378        $cmd->texto = <<<EOD
379SELECT COUNT(idordenador) AS defclients, aulas.*, adm.idadministradorcentro
380  FROM aulas
381 RIGHT JOIN administradores_centros AS adm USING(idcentro)
382 RIGHT JOIN usuarios USING(idusuario)
383  LEFT JOIN ordenadores USING(idaula)
384 WHERE idcentro='$ouid'
385   AND idaula='$labid';
386EOD;
387        $rs=new Recordset;
388        $rs->Comando=&$cmd;
389        if (!$rs->Abrir()) return(false); // Error al abrir recordset
390        $rs->Primero();
391        if (checkParameter($rs->campos["idaula"]) and checkAdmin($rs->campos["idadministradorcentro"])) {
392                $response['id'] = $rs->campos["idaula"];
393                $response['name'] = $rs->campos["nombreaula"];
394                $response['location'] = $rs->campos["ubicacion"];
395                $response['description'] = $rs->campos["comentarios"];
396                $response['inremotepc'] = $rs->campos["inremotepc"]==0 ? false: true;
397                $response['capacity'] = $rs->campos["puestos"];
398                $response['defclients'] = $rs->campos["defclients"];
399                $response['projector'] = $rs->campos["cagnon"]==0 ? false: true;
400                $response['board'] = $rs->campos["pizarra"]==0 ? false: true;
401                $response['routerip'] = $rs->campos["router"];
402                $response['netmask'] = $rs->campos["netmask"];
403                $response['ntp'] = $rs->campos["ntp"];
404                $response['dns'] = $rs->campos["dns"];
405                $response['proxyurl'] = $rs->campos["proxy"];
406                switch ($rs->campos["modomul"]) {
407                        case 1:  $response['mcastmode'] = "half-duplex"; break;
408                        case 2:  $response['mcastmode'] = "full-duplex"; break;
409                        default: $response['mcastmode'] = $rs->campos["modomul"];
410                }
411                $response['mcastip'] = $rs->campos["ipmul"];
412                $response['mcastport'] = $rs->campos["pormul"];
413                $response['mcastspeed'] = $rs->campos["velmul"];
414                $response['p2pmode'] = $rs->campos["modp2p"];
415                $response['p2ptime'] = $rs->campos["timep2p"];
416                $response['image'] = $rs->campos["urlfoto"];
417                jsonResponse(200, $response);
418        }
419        $rs->Cerrar();
420    }
421);
422
423// Listar clientes de un aula.
424$app->get('/ous/:ouid/labs/:labid/clients', 'validateApiKey',
425    function($ouid, $labid) {
426        global $cmd;
427
428        $ouid = htmlspecialchars($ouid);
429        $labid = htmlspecialchars($labid);
430        // Listar los clientes del aula si el usuario de la apikey es admin de su UO.
431        $cmd->texto = <<<EOD
432SELECT ordenadores.*, adm.idadministradorcentro
433  FROM ordenadores
434  JOIN aulas USING(idaula)
435 RIGHT JOIN administradores_centros AS adm USING(idcentro)
436 RIGHT JOIN usuarios USING(idusuario)
437 WHERE idcentro='$ouid'
438   AND idaula='$labid';
439EOD;
440        $rs=new Recordset;
441        $rs->Comando=&$cmd;
442        if (!$rs->Abrir()) return(false);       // Recordset open error.
443        $rs->Primero();
444        if (checkParameter($rs->campos["idaula"]) and checkAdmin($rs->campos["idadministradorcentro"])) {
445                $response['ouid'] = $ouid;
446                $response['labid'] = $labid;
447                $response = array();
448                while (!$rs->EOF) {
449                        $tmp = array();
450                        $tmp['id'] = $rs->campos["idordenador"];
451                        $tmp['name'] = $rs->campos["nombreordenador"];
452                        $tmp['ip'] = $rs->campos["ip"];
453                        $tmp['mac'] = $rs->campos["mac"];
454                        $tmp['ou']['id'] = $ouid;
455                        $tmp['lab']['id'] = $labid;
456                        array_push($response, $tmp);
457                        $rs->Siguiente();
458                }
459                jsonResponse(200, $response);
460        }
461        $rs->Cerrar();
462    }
463);
464
465// Obtener datos de un cliente.
466$app->get('/ous/:ouid/labs/:labid/clients/:clntid', 'validateApiKey',
467    function($ouid, $labid, $clntid) {
468        global $cmd;
469
470        $ouid = htmlspecialchars($ouid);
471        $labid = htmlspecialchars($labid);
472        $clntid = htmlspecialchars($clntid);
473        // Obtener datos del cliente del aula si el usuario de la apikey es admin de su UO.
474        $cmd->texto = <<<EOD
475SELECT ordenadores.*, adm.idadministradorcentro
476  FROM ordenadores
477  JOIN aulas USING(idaula)
478 RIGHT JOIN administradores_centros AS adm USING(idcentro)
479 RIGHT JOIN usuarios USING(idusuario)
480 WHERE idcentro='$ouid'
481   AND idaula='$labid'
482   AND idordenador='$clntid';
483EOD;
484        $rs=new Recordset;
485        $rs->Comando=&$cmd;
486        if (!$rs->Abrir()) return(false); // Error al abrir recordset
487        $rs->Primero();
488        if (checkParameter($rs->campos["idordenador"]) and checkParameter($rs->campos["idaula"]) and checkAdmin($rs->campos["idadministradorcentro"])) {
489                $response['id'] = $rs->campos["idordenador"];
490                $response['name'] = $rs->campos["nombreordenador"];
491                $response['serialno'] = $rs->campos["numserie"];
492                $response['netiface'] = $rs->campos["netiface"];
493                $response['netdriver'] = $rs->campos["netdriver"];
494                $response['mac'] = $rs->campos["mac"];
495                $response['ip'] = $rs->campos["ip"];
496                $response['netmask'] = $rs->campos["mascara"];
497                $response['routerip'] = $rs->campos["router"];
498                $response['repo']['id'] = $rs->campos["idrepositorio"];
499                //$response['hardprofile']['id'] = $rs->campos["idperfilhard"];
500                //$response['menu']['id'] = $rs->campos["idmenu"];
501                $response['validation'] = $rs->campos["validacion"]==0 ? false: true;
502                $response['boottype'] = $rs->campos["arranque"];
503                $response['image'] = $rs->campos["fotoord"];
504                jsonResponse(200, $response);
505        }
506        $rs->Cerrar();
507    }
508);
509
510// Obtener la configuración de hardware de un cliente.
511$app->get('/ous/:ouid/labs/:labid/clients/:clntid/hardware', 'validateApiKey',
512    function($ouid, $labid, $clntid) {
513        global $cmd;
514
515        $ouid = htmlspecialchars($ouid);
516        $labid = htmlspecialchars($labid);
517        $clntid = htmlspecialchars($clntid);
518        $cmd->texto = <<<EOD
519SELECT ordenadores.idordenador, ordenadores.nombreordenador,
520       tipohardwares.nemonico, hardwares.descripcion
521  FROM perfileshard
522 RIGHT JOIN ordenadores USING(idperfilhard)
523  JOIN perfileshard_hardwares USING(idperfilhard)
524  JOIN hardwares ON perfileshard_hardwares.idhardware=hardwares.idhardware
525  JOIN tipohardwares ON tipohardwares.idtipohardware=hardwares.idtipohardware
526 WHERE ordenadores.idordenador='$clntid'
527EOD;
528        $rs=new Recordset;
529        $rs->Comando=&$cmd;
530        if (!$rs->Abrir()) return(false); // Error al abrir recordset
531        $rs->Primero();
532//      if ($ouid != $rs->campos["idcentro"]) ...
533//      if ($labid != $rs->campos["idaula"]) ...
534        if (checkParameter($rs->campos["idordenador"])) {
535                $response['id'] = $rs->campos["idordenador"];
536                $response['name'] = $rs->campos["nombreordenador"];
537                $response['hardware'] = array();
538                while (!$rs->EOF) {
539                        $tmp = array();
540                        $tmp['type'] = $rs->campos["nemonico"];
541                        $tmp['description'] = $rs->campos["descripcion"];
542                        array_push($response['hardware'], $tmp);
543                        $rs->Siguiente();
544                }
545                jsonResponse(200, $response);
546        }
547        $rs->Cerrar();
548    }
549);
550
551// Obtener datos de configuración de discos del cliente.
552$app->get('/ous/:ouid/labs/:labid/clients/:clntid/diskcfg', 'validateApiKey',
553    function($ouid, $labid, $clntid) {
554        global $cmd;
555
556        $ouid = htmlspecialchars($ouid);
557        $labid = htmlspecialchars($labid);
558        $clntid = htmlspecialchars($clntid);
559        $cmd->texto = <<<EOD
560SELECT ordenadores.idordenador AS clientid, ordenadores.nombreordenador,
561       ordenadores_particiones.*, tipospar.tipopar,
562       sistemasficheros.nemonico, nombresos.nombreso, imagenes.nombreca,
563       (imagenes.revision - ordenadores_particiones.revision) AS difimagen
564  FROM ordenadores_particiones
565 RIGHT JOIN ordenadores USING(idordenador)
566  LEFT JOIN tipospar USING(codpar)
567  LEFT JOIN sistemasficheros USING(idsistemafichero)
568  LEFT JOIN nombresos USING(idnombreso)
569  LEFT JOIN imagenes USING(idimagen)
570 WHERE ordenadores.idordenador='$clntid'
571 ORDER BY numdisk ASC, numpar ASC;
572EOD;
573        $rs=new Recordset;
574        $rs->Comando=&$cmd;
575        if (!$rs->Abrir()) return(false); // Error al abrir recordset
576        $rs->Primero();
577//      if ($labid != $rs->campos["idaula"]) ...
578        if (checkParameter($rs->campos["clientid"])) {
579                $response['id'] = $rs->campos["clientid"];
580                $response['name'] = $rs->campos["nombreordenador"];
581                $response['diskcfg'] = array();
582                while (!$rs->EOF) {
583                        if ($rs->campos["numdisk"] == 0) {
584                                $rs->Siguiente();
585                                continue;
586                        }
587                        $tmp = array();
588                        if ($rs->campos["numpar"] == 0) {
589                                $tmp['disk'] = $rs->campos["numdisk"];
590                                switch ($rs->campos["codpar"]) {
591                                        case 1:  $tmp['parttable'] = "MSDOS"; break;
592                                        case 2:  $tmp['parttable'] = "GPT"; break;
593                                        case 3:  $tmp['parttable'] = "LVM"; break;
594                                        case 4:  $tmp['parttable'] = "ZPOOL"; break;
595                                        default: $tmp['parttable'] = $rs->campos["codpar"];
596                                }
597                                $tmp['size'] = $rs->campos["tamano"];
598                        } else {
599                                $tmp['partition'] = $rs->campos["numpar"];
600                                $tmp['parttype'] = $rs->campos["tipopar"];
601                                $tmp['filesystem'] = $rs->campos["nemonico"];
602                                $tmp['size'] = $rs->campos["tamano"];
603                                $tmp['usage'] = $rs->campos["uso"];
604                                if ($rs->campos["nombreso"] != null) {
605                                        $tmp['os'] = $rs->campos["nombreso"];
606                                        if ($rs->campos["idimagen"] > 0) {
607                                                $tmp['image']['id'] = $rs->campos["idimagen"];
608                                                $tmp['image']['deploydate'] = $rs->campos["fechadespliegue"];
609                                                // Comprobar si la imagen está actualizada.
610                                                $tmp['image']['updated'] = ($rs->campos["difimagen"]>0 ? "false" : "true");
611                                        }
612                                }
613                                //$tmp['cachedata'] = $rs->campos["cache"];
614                        }
615                        array_push($response['diskcfg'], $tmp);
616                        $rs->Siguiente();
617                }
618                jsonResponse(200, $response);
619        }
620        $rs->Cerrar();
621    }
622);
623
624// Obtener estado de ejecución del cliente.
625$app->get('/ous/:ouid/labs/:labid/clients/:clntid/status', 'validateApiKey',
626    function($ouid, $labid, $clntid) {
627        global $cmd;
628        global $LONCABECERA;
629        global $LONHEXPRM;
630
631        // Status mapping.
632        $status = array('OFF'=>"off",
633                        'INI'=>"initializing",
634                        'OPG'=>"ogclient",
635                        'BSY'=>"busy",
636                        'LNX'=>"linux",
637                        'WIN'=>"windows");
638        // Parameters.
639        $ouid = htmlspecialchars($ouid);
640        $labid = htmlspecialchars($labid);
641        $clntid = htmlspecialchars($clntid);
642
643        // Database query.
644        $cmd->texto = <<<EOD
645SELECT serv.ipserveradm, serv.portserveradm, clnt.idordenador, clnt.ip
646  FROM entornos AS serv, ordenadores AS clnt
647 WHERE clnt.idordenador='$clntid';
648EOD;
649        $rs=new Recordset;
650        $rs->Comando=&$cmd;
651        if (!$rs->Abrir()) return(false); // Error al abrir recordset
652        $rs->Primero();
653        if (checkParameter($rs->campos["idordenador"])) {
654                // First, try to connect to ogAdmCleint service.
655                $serverip = $rs->campos["ipserveradm"];
656                $serverport = $rs->campos["portserveradm"];
657                $clientid = $rs->campos["idordenador"];
658                $clientip = $rs->campos["ip"];
659
660                // Connect to reset client's status.
661                $reqframe = "nfn=Sondeo\r".
662                            "ido=$clientid\r".
663                            "iph=$clientip\r";
664                $result = sendCommand($serverip, $serverport, $reqframe, $values);
665
666                // Connect to fetch client's status.
667                // Asuming client is off by default.
668                $values["tso"]="OFF";
669                // Iterate to check client's status.
670                // Exit if status!=OFF or end iterations (status=OFF).
671                $maxIter = 30;
672                for ($i=1; $i<$maxIter and preg_match('/OFF/', $values["tso"]); $i++) {
673                        // Connect to check status.
674                        $reqframe = "nfn=respuestaSondeo\r".
675                                    "ido=$clientid\r".
676                                    "iph=$clientip\r";
677                        $result = sendCommand($serverip, $serverport, $reqframe, $values);
678                        // Wait until next checking (0.1 ms).
679                        usleep(100000);
680                }
681
682                // Parse status response.
683                if ($result) {
684                        // Check status type.
685                        if (checkParameter($values["tso"])) {
686                                // Compose JSON response.
687                                $response['id'] = $clientid;
688                                $response['ip'] = $clientip;
689                                $stat = array();
690                                preg_match('/\/[A-Z]*;/', $values["tso"], $stat);
691                                // Check if data exists.
692                                if (empty($stat[0]) or preg_match('/OFF/', $stat[0])) {
693                                        // If no data, check OGAgent API connection.
694                                        $url = "https://$clientip:8000/opengnsys/status";
695                                        $result = multiRequest(Array($url));
696                                        if (empty($result[0])) {
697                                                // Client is off.
698                                                $response['status'] = $status['OFF'];
699                                        } else {
700                                                // Get status and session data.
701                                                $data = json_decode($result[0]);
702                                                if (isset($status[$data->status])) {
703                                                        $response['status'] = $status[$data->status];
704                                                        $response['loggedin'] = $data->loggedin;
705                                                }
706                                        }
707                                } else {
708                                        $response['status'] = $status[substr($stat[0], 1, 3)];
709                                }
710                                if (empty($response['status'])) {
711                                        $response['status'] = "unknown";
712                                }
713                                jsonResponse(200, $response);
714                        }
715                } else {
716                        // Access error.
717                        $response['message'] = "Cannot access to OpenGnsys server";
718                        jsonResponse(500, $response);
719                }
720        }
721        $rs->Cerrar();
722    }
723);
724
725
726// Listar repositorios.
727$app->get('/ous/:ouid/repos', 'validateApiKey',
728    function($ouid) {
729        global $cmd;
730
731        $ouid = htmlspecialchars($ouid);
732        // Listar las salas de la UO si el usuario de la apikey es su admin.
733        // Consulta temporal,
734        $cmd->texto = "SELECT * FROM repositorios WHERE idcentro='$ouid';";
735        $rs=new Recordset;
736        $rs->Comando=&$cmd;
737        if (!$rs->Abrir()) return(false); // Error al abrir recordset
738        $rs->Primero();
739        // Comprobar que exista la UO.
740        if (checkParameter($rs->campos["idcentro"])) {
741                $response = array();
742                while (!$rs->EOF) {
743                        $tmp = array();
744                        $tmp['id'] = $rs->campos["idrepositorio"];
745                        $tmp['name'] = $rs->campos["nombrerepositorio"];
746                        $tmp['ou']['id'] = $ouid;
747                        array_push($response, $tmp);
748                        $rs->Siguiente();
749                }
750                jsonResponse(200, $response);
751        }
752        $rs->Cerrar();
753    }
754);
755
756// Obtener datos de un repositorio.
757$app->get('/ous/:ouid/repos/:repoid', 'validateApiKey',
758    function($ouid, $repoid) {
759        global $cmd;
760
761        $ouid = htmlspecialchars($ouid);
762        $repoid = htmlspecialchars($repoid);
763        $cmd->texto = "SELECT * FROM repositorios WHERE idrepositorio='$repoid';";
764        $rs=new Recordset;
765        $rs->Comando=&$cmd;
766        if (!$rs->Abrir()) return(false); // Error al abrir recordset
767        $rs->Primero();
768        // Comprobar que exista el repositorio.
769        if (checkParameter($rs->campos["idrepositorio"])) {
770                $response['id'] = $rs->campos["idrepositorio"];
771                $response['name'] = $rs->campos["nombrerepositorio"];
772                $response['description'] = $rs->campos["comentarios"];
773                $response['ip'] = $rs->campos["ip"];
774                //$response['port'] = $rs->campos["puertorepo"];
775                jsonResponse(200, $response);
776        }
777        $rs->Cerrar();
778    }
779);
780
781// Listar imágenes.
782$app->get('/ous/:ouid/images', 'validateApiKey',
783    function($ouid) {
784        global $cmd;
785
786        $ouid = htmlspecialchars($ouid);
787        // Listar las salas de la UO si el usuario de la apikey es su admin.
788        // Consulta temporal,
789        $cmd->texto = "SELECT * FROM imagenes WHERE idcentro='$ouid';";
790        $rs=new Recordset;
791        $rs->Comando=&$cmd;
792        if (!$rs->Abrir()) return(false); // Error al abrir recordset
793        // Comprobar que exista la UO.
794        $rs->Primero();
795        if (checkParameter($rs->campos["idcentro"])) {
796                $response = array();
797                while (!$rs->EOF) {
798                        $tmp = array();
799                        $tmp['id'] = $rs->campos["idimagen"];
800                        $tmp['name'] = $rs->campos["nombreca"];
801                        $tmp['inremotepc'] = $rs->campos["inremotepc"]==0 ? false: true;
802                        $tmp['ou']['id'] = $ouid;
803                        array_push($response, $tmp);
804                        $rs->Siguiente();
805                }
806                jsonResponse(200, $response);
807        }
808    }
809);
810
811// Obtener datos de una imagen.
812$app->get('/ous/:ouid/images/:imgid', 'validateApiKey',
813    function($ouid, $imgid) {
814        global $cmd;
815
816        $ouid = htmlspecialchars($ouid);
817        $imgid = htmlspecialchars($imgid);
818        $cmd->texto = "SELECT * FROM imagenes WHERE idimagen='$imgid';";
819        $rs=new Recordset;
820        $rs->Comando=&$cmd;
821        if (!$rs->Abrir()) return(false); // Error al abrir recordset
822        $rs->Primero();
823        // Comprobar que exista el repositorio.
824        if (checkParameter($rs->campos["idimagen"])) {
825                $response['id'] = $rs->campos["idimagen"];
826                $response['name'] = $rs->campos["nombreca"];
827                $response['description'] = $rs->campos["descripcion"];
828                $response['comments'] = $rs->campos["comentarios"];
829                $response['inremotepc'] = $rs->campos["inremotepc"]==0 ? false: true;
830                $response['repo']['id'] = $rs->campos["idrepositorio"];
831                switch ($rs->campos["tipo"]) {
832                        case 1:  $response['type'] = "monolithic"; break;
833                        case 2:  $response['type'] = "base"; break;
834                        case 3:  $response['type'] = "incremental";
835                                 $response['baseimg'] = $rs->campos["imagenid"];
836                                 $response['path'] = $rs->campos["ruta"];
837                                 break;
838                        default: $response['type'] = $rs->campos["tipo"];
839                }
840                if ($rs->campos["idordenador"] != 0) {
841                        $response['client']['id'] = $rs->campos["idordenador"];
842                        $response['client']['disk'] = $rs->campos["numdisk"];
843                        $response['client']['partition'] = $rs->campos["numpar"];
844                        $response['creationdate'] = $rs->campos["fechacreacion"];
845                        $response['release'] = $rs->campos["revision"];
846                }
847                jsonResponse(200, $response);
848        }
849        $rs->Cerrar();
850    }
851);
852
853// Lista de softeare instalado en una imagen.
854$app->get('/ous/:ouid/images/:imgid/software', 'validateApiKey',
855    function($ouid, $imgid) {
856        global $cmd;
857
858        $ouid = htmlspecialchars($ouid);
859        $imgid = htmlspecialchars($imgid);
860        $cmd->texto = <<<EOD
861SELECT imagenes.idimagen, imagenes.nombreca, nombresos.nombreso, softwares.descripcion
862  FROM perfilessoft
863 RIGHT JOIN imagenes USING(idperfilsoft)
864  LEFT JOIN nombresos USING(idnombreso)
865  LEFT JOIN perfilessoft_softwares USING(idperfilsoft)
866  LEFT JOIN softwares USING(idsoftware)
867 WHERE imagenes.idimagen='$imgid'
868 ORDER BY softwares.descripcion ASC;
869EOD;
870        $rs=new Recordset;
871        $rs->Comando=&$cmd;
872        if (!$rs->Abrir()) return(false);       // Error al abrir recordset
873        $rs->Primero();
874        // Comprobar que exista el repositorio.
875        if (checkParameter($rs->campos["idimagen"])) {
876                $response['id'] = $rs->campos["idimagen"];
877                $response['name'] = $rs->campos["nombreca"];
878                $response['os'] = $rs->campos["nombreso"];
879                //$response['ostype'] = Tipo de SO (agrupar en array con nombre SO).
880                $response['software'] = array();
881                while (!$rs->EOF) {
882                        if ($rs->campos["descripcion"] == null) {
883                                $rs->Siguiente();
884                                continue;
885                        }
886                        $tmp = array();
887                        $tmp['application'] = $rs->campos["descripcion"];
888                        array_push($response['software'], $tmp);
889                        $rs->Siguiente();
890                }
891                jsonResponse(200, $response);
892        }
893        $rs->Cerrar();
894    }
895);
896
897// Arrancar un ordenador con una imagen instalada, elegido al azar.
898$app->get('/ous/:id1/images/:id2/boot', 'validateApiKey',
899    function($ouid, $imageid) {
900        global $cmd;
901        global $AMBITO_ORDENADORES;
902        global $EJECUCION_COMANDO;
903        global $ACCION_INICIADA;
904        global $ACCION_SINRESULTADO;
905
906        // Pparameters.
907        $ouid = htmlspecialchars($ouid);
908        $imegeid = htmlspecialchars($imageid);
909        // Boot 1 client.
910        $nclients = 1;
911
912        // Query: server data and all clients' boot data availabe for Remote PC with this image installed (random order).
913        $cmd->texto = <<<EOD
914SELECT s.ipserveradm, s.portserveradm,
915       c.idordenador, c.ip, c.mac, p.numdisk, p.numpar
916  FROM entornos AS s, ordenadores AS c
917  JOIN aulas USING(idaula)
918  JOIN centros USING(idcentro)
919  JOIN ordenadores_particiones AS p USING(idordenador)
920  JOIN imagenes USING(idimagen)
921 WHERE centros.idcentro='$ouid'
922   AND aulas.inremotepc=1
923   AND imagenes.idimagen='$imageid'
924   AND imagenes.inremotepc=1
925 ORDER BY RAND();
926EOD;
927        $rs=new Recordset;
928        $rs->Comando=&$cmd;
929        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
930        $rs->Primero();
931        if (checkParameter($rs->campos["ipserveradm"])) {
932
933                $response['imageid'] = $imageid;
934                $response['sendto'] = array();
935
936                // AVISO: Procesar datos del servidor (solo 1er registro).
937
938                $serverip = $rs->campos["ipserveradm"];
939                $serverport = $rs->campos["portserveradm"];
940
941                // AVISO: Procesar datos de los clientes.
942
943                $clientid = array();
944                $clientip = array();
945                $clientmac = array();
946                $clientdisk = array();
947                $clientpart = array();
948                while (!$rs->EOF) {
949                        array_push($clientid, $rs->campos["idordenador"]);
950                        array_push($clientip, $rs->campos["ip"]);
951                        array_push($clientmac, $rs->campos["mac"]);
952                        array_push($clientdisk, $rs->campos["numdisk"]);
953                        array_push($clientpart, $rs->campos["numpar"]);
954                        $rs->Siguiente();
955                }
956                $rs->Cerrar();
957
958                // AVISO: consultar el estado de todos los clientes y
959                //        quitar aquellos que no tengan "OFF", "OPG" o ""
960                //        (estudiar si incluir los "BSY")
961
962                // Reset clients' status.
963                $reqframe = "nfn=Sondeo\r".
964                            "ido=".implode(',', $clientid)."\r".
965                            "iph=".implode(';', $clientip)."\r";
966                sendCommand($serverip, $serverport, $reqframe, $values);
967                 // Wait to get response.
968                sleep(3);
969                // Connect to check status.
970                $reqframe = "nfn=respuestaSondeo\r".
971                            "ido=".implode(',', $clientid)."\r".
972                            "iph=".implode(';', $clientip)."\r";
973                sendCommand($serverip, $serverport, $reqframe, $values);
974                // Check status type.
975                if (isset($values["tso"])) {
976                        preg_match_all('/[A-Z]{3}/', $values["tso"], $stat);
977                }
978                if (isset($stat[0])) {
979                        for ($i=0; $i<sizeof($stat[0]); $i++) {
980                                if (! in_array($stat[0][$i], array("OFF", "OPG", ""))) {
981                                        unset($clientid[$i]);
982                                        unset($clientip[$i]);
983                                        unset($clientmac[$i]);
984                                        unset($clientdisk[$i]);
985                                        unset($clientpart[$i]);
986                                }
987                        }
988                }
989
990                // AVISO: el siguiente código inicia un único cliente.
991                //        Para iniciar varios:
992                //        - id. clientes separados por carácter ','.
993                //        - IP clientes separadas por carácter ';'
994                //        - MAC clientes separadas por carácter ';'
995
996                // Executing boot command.
997                $reqframe = "nfn=Arrancar\r".
998                            "ido=".implode(',', $clientid)."\r".
999                            "iph=".implode(';', $clientip)."\r".
1000                            "mac=".implode(';', $clientmac)."\r".
1001                            "mar=1\r";
1002echo "req=".str_replace("\r"," ",$reqframe).".\n";
1003                sendCommand($serverip, $serverport, $reqframe, $values);
1004                if ($values["res"]) {
1005print_r($values);
1006                        $tmp = array();
1007                        for ($i=0, $boot=0; $i<sizeof($clientid) and $boot!=1; $i++) {
1008                                $reqframe = "nfn=IniciarSesion\r".
1009                                            "ido=".$clientid[$i]."\r".
1010                                            "iph=".$clientip[$i]."\r".
1011                                            "dsk=".$clientdisk[$i]."\r".
1012                                            "par=".$clientpart[$i]."\r";
1013echo "i=$i: req=".str_replace("\r"," ",$reqframe).".\n";
1014                                sendCommand($serverip, $serverport, $reqframe, $values);
1015                                if ($values["res"]) {
1016
1017                                        // AVISO: incluir comando Iniciar sesión en cola de acciones.
1018                                        $timestamp=time();
1019                                        $cmd->texto = <<<EOD
1020INSERT INTO acciones
1021        SET tipoaccion=$EJECUCION_COMANDO,
1022            idtipoaccion=9,
1023            idcomando=9,
1024            parametros='nfn=IniciarSesion\rdsk=$clientdisk[$i]\rpar=$clientpart[$i]',
1025            descriaccion='RemotePC Session',
1026            idordenador=$clientid[$i],
1027            ip='$clientip[$i]',
1028            sesion=$timestamp,
1029            fechahorareg=NOW(),
1030            estado=$ACCION_INICIADA,
1031            resultado=$ACCION_SINRESULTADO,
1032            ambito=$AMBITO_ORDENADORES,
1033            idambito=$clientid[$i],
1034            restrambito='$clientip[$i]',
1035            idcentro=$ouid;
1036EOD;
1037                                        $result = $cmd->Ejecutar();
1038                                        if ($result) {
1039                                                $tmp['id'] = $clientid[$i];
1040                                                $tmp['ip'] = $clientip[$i];
1041                                                $tmp['mac'] = $clientmac[$i];
1042                                                array_push($response['sendto'], $tmp);
1043                                                $boot = 1;
1044                                        }
1045                                }
1046                        }
1047                }
1048                jsonResponse(200, $response);
1049        }
1050    }
1051);
1052// Alternativa como método GET.
1053//$app->get('/ous/:id1/images/:id2/boot/:number', 'validateApiKey',
1054//    function($ouid, $imageid, $number) {
1055//
1056//   }
1057//);
1058
1059?>
Note: See TracBrowser for help on using the repository browser.