source: admin/WebConsole/rest/repository.php @ 240a4dc

918-git-images-111dconfigure-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-instalacion
Last change on this file since 240a4dc was b45357d, checked in by Ramón M. Gómez <ramongomez@…>, 5 years ago

#932: REST route POST /repository/poweron accepts MAC addresses without colon characters.

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[15acccd]1<?php
2/**
[fb2ee20]3 * @file    repository.php
4 * @brief   OpenGnsys Repository REST API manager.
[15acccd]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  Juan Manuel Bardallo SIC Universidad de Huelva
[b45357d]9 * @version 1.1.0
[15acccd]10 * @date    2016-04-06
11 */
12
[2b00219]13
[b45357d]14// Auxiliary functions.
[15acccd]15/**
16 * @brief    Validate API key included in "Authorization" HTTP header.
17 * @return   JSON response on error.
18 */
19function validateRepositoryApiKey() {
[b45357d]20        $response = [];
[e3b5585]21        $app = \Slim\Slim::getInstance();
[15acccd]22
[41c430a]23        // Assign user id. that match this key to global variable.
24        @$apikey = htmlspecialchars(function_exists('apache_request_headers') ? apache_request_headers()['Authorization'] : $_SERVER['HTTP_AUTHORIZATION']);
25        if (isset($apikey)) {
26                // fetch repository token from ogAdmRepo.cfg configuration file.
[e57b608]27                @$confFile = parse_ini_file(__DIR__ . '/../../etc/ogAdmRepo.cfg', 'r');
28                if (isset($confFile)) {
[41c430a]29                        if(@strcmp($apikey, $confFile['ApiToken']) == 0) {
30                                // Credentials OK.
31                                return true;
32                        } else {
[15acccd]33                                // Credentials error.
34                                $response['message'] = 'Login failed. Incorrect credentials';
35                                jsonResponse(401, $response);
36                                $app->stop();
37                        }
38                } else {
[a38cb26]39                        // Cannot access configuration file.
[15acccd]40                        $response['message'] = "An error occurred, please try again";
41                        jsonResponse(500, $response);
[41c430a]42                        $app->stop();
[15acccd]43                }
44        } else {
45                // Error: missing API key.
46                $response['message'] = 'Missing Repository API key';
47                jsonResponse(400, $response);
[41c430a]48                $app->stop();
[15acccd]49        }
50}
51
52function commandExist($cmd) {
53    $returnVal = shell_exec("which $cmd");
54    return (empty($returnVal) ? false : true);
55}
56
[338b30e]57
[b45357d]58// REST routes.
[15acccd]59
60
61/**
62 * @brief    List all images in the repository
[72bbcf8]63 * @note     Route: /repository/images, Method: GET
[b45357d]64 * @return   string  JSON object with directory, images array, ous array and disk data.
[15acccd]65 */
[72bbcf8]66$app->get('/repository/images(/)', 'validateRepositoryApiKey',
[338b30e]67    function() use ($app) {
[b45357d]68        $response = [];
[338b30e]69        // Read repository information file.
70        $cfgFile = '/opt/opengnsys/etc/repoinfo.json';
71        $response = json_decode(@file_get_contents($cfgFile), true);
72        // Check if directory exists.
73        $imgPath = @$response['directory'];
74        if (is_dir($imgPath)) {
[e3b5585]75                // Complete global image information.
[338b30e]76                for ($i=0; $i<sizeof(@$response['images']); $i++) {
[72bbcf8]77                        $img = $response['images'][$i];
78                        $file = $imgPath."/".($img['type']==="dir" ? $img["name"] : $img["name"].".".$img["type"]);
[338b30e]79                        $response['images'][$i]['size'] = @stat($file)['size'];
[72bbcf8]80                        $response['images'][$i]['modified'] = date("Y-m-d H:i:s", @stat($file)['mtime']);
[338b30e]81                        $response['images'][$i]['mode'] = substr(decoct(@stat($file)['mode']), -4);
[3b8d1ea]82                        $backupfile = "$file.ant";
[9d773c0]83                        if (file_exists($backupfile)) {
84                                $response['images'][$i]['backedup'] = true;
85                                $response['images'][$i]['backupsize'] = @stat($backupfile)['size'];
86                        } else {
87                                $response['images'][$i]['backedup'] = false;
88                        }
[3b8d1ea]89                        $lockfile = "$file.lock";
90                        $response['images'][$i]['locked'] = file_exists($lockfile);
[15acccd]91                }
[e3b5585]92                // Complete image in OUs information.
93                for ($j=0; $j<sizeof(@$response['ous']); $j++) {
94                        for ($i=0; $i<sizeof(@$response['ous'][$j]['images']); $i++) {
[72bbcf8]95                                $img = $response['ous'][$j]['images'][$i];
96                                $file = $imgPath."/".$response['ous'][$j]['subdir']."/".($img['type']==="dir" ? $img["name"] : $img["name"].".".$img["type"]);
[e3b5585]97                                $response['ous'][$j]['images'][$i]['size'] = @stat($file)['size'];
[72bbcf8]98                                $response['ous'][$j]['images'][$i]['modified'] = date("Y-m-d H:i:s", @stat($file)['mtime']);
[e3b5585]99                                $response['ous'][$j]['images'][$i]['mode'] = substr(decoct(@stat($file)['mode']), -4);
[3b8d1ea]100                                $response['ous'][$j]['images'][$i]['backedup'] = false;
101                                $lockfile = "$file.lock";
102                                $response['ous'][$j]['images'][$i]['locked'] = file_exists($lockfile);
[e3b5585]103                        }
104                }
[338b30e]105                // Retrieve disk information.
[72bbcf8]106                $total = disk_total_space($imgPath);
107                $free = disk_free_space($imgPath);
[d610135]108                $response['disk']['total'] = $total;
109                $response['disk']['free'] = $free;
[338b30e]110                // JSON response.
111                jsonResponse(200, $response);
112        } else {
113                // Print error message.
114                $response['message'] = 'Images directory not found';
115                jsonResponse(404, $response);
[15acccd]116        }
[338b30e]117        $app->stop();
118    }
[15acccd]119);
120
121
122/**
[bdee878]123 * @brief    List image data
124 * @note     Route: /repository/image/:imagename, Method: GET
[b45357d]125 * @return   string  JSON object with image data.
[bdee878]126 */
[e368226]127$app->get('/repository/image(/:ouname)/:imagename(/)', 'validateRepositoryApiKey',
128    function($ouname="/", $imagename) use ($app) {
[b45357d]129        $images = [];
130        $response = [];
[bdee878]131        // Search image name in repository information file.
132        $cfgFile = '/opt/opengnsys/etc/repoinfo.json';
133        $json = json_decode(@file_get_contents($cfgFile), true);
134        $imgPath = @$json['directory'];
[e368226]135        if (empty($ouname) or $ouname == "/") {
136                // Search in global directory.
137                $images = @$json['images'];
138        } else {
139                // Search in OU directory.
140                for ($i=0; $i<sizeof(@$json['ous']); $i++) {
141                        if ($json['ous'][$i]['subdir'] == $ouname) {
142                                $images = $json['ous'][$i]['images'];
143                        }
144                }
145        }
146        // Search image.
147        foreach ($images as $img) {
[bdee878]148                if ($img['name'] == $imagename) {
[e368226]149                        $response = $img;
150                        $file = "$imgPath/$ouname/" . ($img['type']==="dir" ? $img["name"] : $img["name"].".".$img["type"]);
151                        $response['size'] = @stat($file)['size'];
152                        $response['modified'] = date("Y-m-d H:i:s", @stat($file)['mtime']);
153                        $response['mode'] = substr(decoct(@stat($file)['mode']), -4);
[3b8d1ea]154                        $backupfile = "$file.ant";
[bdee878]155                        if (file_exists($backupfile)) {
[e368226]156                                $response['backedup'] = true;
157                                $response['backupsize'] = @stat($backupfile)['size'];
[bdee878]158                        } else {
[e368226]159                                $response['backedup'] = false;
[bdee878]160                        }
[3b8d1ea]161                        $lockfile = "$file.lock";
162                        $response['locked'] = file_exists($lockfile);
[bdee878]163                }
164        }
[e368226]165        if (isset ($response)) {
[bdee878]166                // JSON response.
167                jsonResponse(200, $response);
168        } else {
169                // Print error message.
170                $response['message'] = 'Image not found';
171                jsonResponse(404, $response);
172        }
173        $app->stop();
174    }
175);
176
177
178/**
[15acccd]179 * @brief    Power on a pc or group of pcs with the MAC specified in POST parameters
180 * @note     Route: /poweron, Method: POST
[b45357d]181 * @param    array   Array of MAC addresses
182 * @return   string  JSON string ok if the power on command was sent
[15acccd]183 */
184$app->post('/repository/poweron', 'validateRepositoryApiKey',
[fce0af3]185    function() use($app) {
[b45357d]186                $response = [];
[e57b608]187                // The macs parameter must come in the post (JSON object with array of MACs)
188                $data = json_decode($app->request()->getBody());
189                if (empty($data->macs)) {
190                        // Print error message.
191                        $response['message'] = 'Required param macs not found';
192                        jsonResponse(400, $response);
193                } else {
194                        // Execute local wakeonlan command (may be installed)
195                        if(commandExist("wakeonlan")) {
196                                $strMacs = trim(implode(' ', $data->macs));
[b45357d]197                                if(stristr($strMacs, ':') === false) {
198                                        $strMacs = implode(':', str_split($strMacs, 2));
199                                }
[e57b608]200                                $response["output"] = "Executing wakeonlan ".$strMacs."\n";
201                                $response["output"] .= shell_exec("wakeonlan ".$strMacs);
202                                jsonResponse(200, $response);
[a5f7c30]203                        } else {
[e57b608]204                                // Print error message.
205                                $response['message'] = 'Wakeonlan command not found in this repository';
206                                jsonResponse(404, $response);
[15acccd]207                        }
208                }
[e57b608]209                $app->stop();
[15acccd]210        }
211);
212
Note: See TracBrowser for help on using the repository browser.