]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Add json output option to show storages and show single storage endpoints
authorMarcin Haba <marcin.haba@bacula.pl>
Sun, 22 Nov 2020 07:53:11 +0000 (08:53 +0100)
committerMarcin Haba <marcin.haba@bacula.pl>
Sun, 22 Nov 2020 07:53:11 +0000 (08:53 +0100)
gui/baculum/protected/API/Class/StatusStorage.php
gui/baculum/protected/API/Pages/API/StorageShow.php
gui/baculum/protected/API/Pages/API/StoragesShow.php
gui/baculum/protected/API/openapi_baculum.json

index 085ef09e76ce4b829858ec4319cf0067f8af3175..4a74b1e1cd98cb62a15248626e2d3de25c44bdfa 100644 (file)
@@ -3,7 +3,7 @@
  * Bacula(R) - The Network Backup Solution
  * Baculum   - Bacula web interface
  *
- * Copyright (C) 2013-2019 Kern Sibbald
+ * Copyright (C) 2013-2020 Kern Sibbald
  *
  * The main author of Baculum is Marcin Haba.
  * The original author of Bacula is Kern Sibbald, with contributions
@@ -71,26 +71,62 @@ class StatusStorage extends ComponentStatusModule {
         * @return array array with parsed storage status values
         */
        public function parseStatus(array $output, $type) {
-               $result = array();
+               $result = [];
                $line = null;
-               $opts = array();
+               $part = [];
+               $autochanger = null;
+               $autochangers = [];
+               $ach_dev = [];
+               $empty_lines = 0;
                for($i = 0; $i < count($output); $i++) {
                        if (empty($output[$i])) {
-                               if  (count($opts) > 10) {
-                                       $result[] = $opts;
+                               $empty_lines++;
+                               if  (count($part) > 10) {
+                                       $result[] = $part;
+                                       $part = [];
                                }
-                               if (count($opts) > 0) {
-                                       $opts = array();
+                               if (count($ach_dev) == 2) {
+                                       $autochangers[$autochanger]['devices'][]  = $ach_dev;
+                                       $ach_dev = [];
+                               }
+                               if ($empty_lines == 4 && $autochanger) {
+                                       $autochanger = null;
                                }
                        } else {
+                               $empty_lines = 0;
                                $line = $this->parseLine($output[$i]);
-                               if (is_array($line)) {
-                                       $opts[$line['key']] = $line['value'];
+                               if (!is_array($line)) {
+                                       continue;
+                               }
+
+                               if ($line['key'] == 'autochanger') {
+                                       $autochanger  = $line['value'];
+                                       $autochangers[$autochanger] = ['devices' => []];
+                               } elseif ($autochanger) {
+                                       $ach_dev[$line['key']] = $line['value'];
+                               } else {
+                                       $part[$line['key']] = $line['value'];
                                }
                        }
                }
                if ($type === self::OUTPUT_TYPE_HEADER) {
                        $result = array_pop($result);
+               } elseif ($type === self::OUTPUT_TYPE_DEVICES) {
+                       for ($i = 0; $i < count($result); $i++) {
+                               $found = false;
+                               foreach ($autochangers as $ach => $devs) {
+                                       for ($j = 0; $j < count($devs['devices']); $j++) {
+                                               if ($result[$i]['name'] === $devs['devices'][$j]['name']) {
+                                                       $result[$i]['autochanger'] = $ach;
+                                                       $found = true;
+                                                       break 2;
+                                               }
+                                       }
+                               }
+                               if (!$found) {
+                                       $result[$i]['autochanger'] = null;
+                               }
+                       }
                }
                return $result;
        }
index 918b8269aa557932722ae9d489754c484d868b1a..4bfc4caf8aeba5a67f93ccac7bed60660d39340f 100644 (file)
@@ -3,7 +3,7 @@
  * Bacula(R) - The Network Backup Solution
  * Baculum   - Bacula web interface
  *
- * Copyright (C) 2013-2019 Kern Sibbald
+ * Copyright (C) 2013-2020 Kern Sibbald
  *
  * The main author of Baculum is Marcin Haba.
  * The original author of Bacula is Kern Sibbald, with contributions
@@ -20,6 +20,8 @@
  * Bacula(R) is a registered trademark of Kern Sibbald.
  */
  
+Prado::using('Application.API.Class.ConsoleOutputPage');
+
 /**
  * Show storage command endpoint.
  *
  * @category API
  * @package Baculum API
  */
-class StorageShow extends BaculumAPIServer {
+class StorageShow extends ConsoleOutputPage {
        public function get() {
                $storageid = $this->Request->contains('id') ? intval($this->Request['id']) : 0;
+               $out_format = $this->Request->contains('output') && $this->isOutputFormatValid($this->Request['output']) ? $this->Request['output'] : parent::OUTPUT_FORMAT_RAW;
                $result = $this->getModule('bconsole')->bconsoleCommand(
                        $this->director,
-                       array('.storage')
+                       array('.storage'),
+                       null,
+                       true
                );
                if ($result->exitcode === 0) {
-                       array_shift($result->output);
                        $storage = $this->getModule('storage')->getStorageById($storageid);
                        if (is_object($storage) && in_array($storage->name, $result->output)) {
-                               $result = $this->getModule('bconsole')->bconsoleCommand(
-                                       $this->director,
-                                       array('show', 'storage="' . $storage->name . '"')
-                               );
-                               $this->output = $result->output;
-                               $this->error = $result->exitcode;
+                               $out = (object)['output' => [], 'exitcode' => 0];
+                               if ($out_format === parent::OUTPUT_FORMAT_RAW) {
+                                       $out = $this->getRawOutput(['storage' => $storage->name]);
+                               } elseif($out_format === parent::OUTPUT_FORMAT_JSON) {
+                                       $out = $this->getJSONOutput(['storage' => $storage->name]);
+                               }
+                               $this->output = $out->output;
+                               $this->error = $out->exitcode;
                        } else {
                                $this->output = StorageError::MSG_ERROR_STORAGE_DOES_NOT_EXISTS;
                                $this->error = StorageError::ERROR_STORAGE_DOES_NOT_EXISTS;
@@ -53,6 +59,52 @@ class StorageShow extends BaculumAPIServer {
                        $this->error = $result->exitcode;
                }
        }
+
+       /**
+        * Get show storage output from console in raw format.
+        *
+        * @param array $params command  parameters
+        * @return StdClass object with output and exitcode
+        */
+       protected function getRawOutput($params = []) {
+               $result = $this->getModule('bconsole')->bconsoleCommand(
+                       $this->director,
+                       array('show', 'storage="' . $params['storage'] . '"'),
+                       null,
+                       true
+               );
+               return $result;
+       }
+
+       /**
+        * Get show storage output in JSON format.
+        *
+        * @param array $params command parameters
+        * @return StdClass object with output and exitcode
+        */
+       protected function getJSONOutput($params = []) {
+               $result = (object)['output' => [], 'exitcode' => 0];
+               $output = $this->getRawOutput($params);
+               if ($output->exitcode === 0) {
+                       for ($i = 0; $i < count($output->output); $i++) {
+                               if (preg_match_all('/(?<=\s)\w+=.+?(?=\s+\w+=.+|$)/i', $output->output[$i], $matches) > 0) {
+                                       for ($j = 0; $j < count($matches[0]); $j++) {
+                                               list($key, $value) = explode('=', $matches[0][$j], 2);
+                                               if (key_exists($key, $result->output)) {
+                                                       /*
+                                                        * The most important options are in first lines.
+                                                        * If keys are double skip the second ones
+                                                        */
+                                                       continue;
+                                               }
+                                               $result->output[strtolower($key)] = $value;
+                                       }
+                               }
+                       }
+               }
+               $result->exitcode = $output->exitcode;
+               return $result;
+       }
 }
 
 ?>
index 32bd3dd24d73dc2eb8f8fbd9641a7bdda7b1962b..be449c6455ea69c29e74ca3368247731a2897be1 100644 (file)
@@ -3,7 +3,7 @@
  * Bacula(R) - The Network Backup Solution
  * Baculum   - Bacula web interface
  *
- * Copyright (C) 2013-2019 Kern Sibbald
+ * Copyright (C) 2013-2020 Kern Sibbald
  *
  * The main author of Baculum is Marcin Haba.
  * The original author of Bacula is Kern Sibbald, with contributions
@@ -20,6 +20,8 @@
  * Bacula(R) is a registered trademark of Kern Sibbald.
  */
  
+Prado::using('Application.API.Class.ConsoleOutputPage');
+
 /**
  * Show storages command endpoint.
  *
  * @category API
  * @package Baculum API
  */
-class StoragesShow extends BaculumAPIServer {
+class StoragesShow extends ConsoleOutputPage {
 
        public function get() {
+               $out_format = $this->Request->contains('output') && $this->isOutputFormatValid($this->Request['output']) ? $this->Request['output'] : parent::OUTPUT_FORMAT_RAW;
                $result = $this->getModule('bconsole')->bconsoleCommand(
                        $this->director,
-                       array('.storage')
+                       array('.storage'),
+                       null,
+                       true
                );
                $storage = null;
                if ($result->exitcode === 0) {
-                       array_shift($result->output);
                        if ($this->Request->contains('name')) {
                                if (in_array($this->Request['name'], $result->output)) {
                                        $storage = $this->Request['name'];
@@ -51,18 +55,76 @@ class StoragesShow extends BaculumAPIServer {
                        $this->error = $result->exitcode;
                        return;
                }
+
+               $out = (object)['output' => [], 'exitcode' => 0];
+               if ($out_format === parent::OUTPUT_FORMAT_RAW) {
+                       $out = $this->getRawOutput(['storage' => $storage]);
+               } elseif($out_format === parent::OUTPUT_FORMAT_JSON) {
+                       $out = $this->getJSONOutput(['storage' => $storage]);
+               }
+
+               $this->output = $out->output;
+               $this->error = $out->exitcode;
+       }
+
+       /**
+        * Get show storage output from console in raw format.
+        *
+        * @param array $params command  parameters
+        * @return StdClass object with output and exitcode
+        */
+       protected function getRawOutput($params = []) {
                $cmd = array('show');
-               if (is_string($storage)) {
-                       $cmd[] = 'storage="' . $storage . '"';
+               if (is_string($params['storage'])) {
+                       $cmd[] = 'storage="' . $params['storage'] . '"';
                } else {
                        $cmd[] = 'storages';
                }
                $result = $this->getModule('bconsole')->bconsoleCommand(
                        $this->director,
-                       $cmd
+                       $cmd,
+                       true
                );
-               $this->output = $result->output;
-               $this->error = $result->exitcode;
+               return $result;
+       }
+
+       /**
+        * Get show storage output in JSON format.
+        *
+        * @param array $params command parameters
+        * @return StdClass object with output and exitcode
+        */
+       protected function getJSONOutput($params = []) {
+               $result = (object)['output' => [], 'exitcode' => 0];
+               $output = $this->getRawOutput($params);
+               if ($output->exitcode === 0) {
+                       $part = [];
+                       for ($i = 0; $i < count($output->output); $i++) {
+                               if (preg_match_all('/(?<=\s)\w+=.+?(?=\s+\w+=.+|$)/i', $output->output[$i], $matches) > 0) {
+                                       for ($j = 0; $j < count($matches[0]); $j++) {
+                                               list($key, $value) = explode('=', $matches[0][$j], 2);
+                                               if (key_exists($key, $result->output)) {
+                                                       /*
+                                                        * The most important options are in first lines.
+                                                        * If keys are double skip the second ones
+                                                        */
+                                                       continue;
+                                               }
+                                               if ($key == 'name' && count($part) > 0) {
+                                                       $result->output[] = $part;
+                                                       $part = [];
+                                               }
+                                               $part[strtolower($key)] = $value;
+                                       }
+                               }
+                       }
+                       if (count($part) > 0) {
+                               $result->output[] = $part;
+                               $part = [];
+                       }
+               }
+               $result->exitcode = $output->exitcode;
+               return $result;
        }
 }
 ?>
index 4522733826d445b80ec7fb73378af2cf174d6d02..9d704658604a0ad7e821dc05a263b8481fd5937e 100644 (file)
                                                }
                                        }
                                },
-                               "parameters": [{
-                                       "$ref": "#/components/parameters/StorageId"
-                               }]
+                               "parameters": [
+                                       {
+                                               "$ref": "#/components/parameters/StorageId"
+                                       },
+                                       {
+                                               "$ref": "#/components/parameters/Output"
+                                       }
+                               ]
                        }
                },
                "/api/v1/storages/{storageid}/status": {
                                                        "type": "string",
                                                        "pattern": "[a-zA-Z0-9:.-_ ]+"
                                                }
+                                       },
+                                       {
+                                               "$ref": "#/components/parameters/Output"
                                        }
                                ]
                        }