]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Add status director and status storage endpoints
authorMarcin Haba <marcin.haba@bacula.pl>
Thu, 9 Aug 2018 19:59:55 +0000 (21:59 +0200)
committerMarcin Haba <marcin.haba@bacula.pl>
Fri, 10 Aug 2018 17:27:06 +0000 (19:27 +0200)
gui/baculum/protected/API/Class/ComponentStatusModule.php [new file with mode: 0644]
gui/baculum/protected/API/Class/DirectorStatus.php [new file with mode: 0644]
gui/baculum/protected/API/Class/StorageStatus.php [new file with mode: 0644]
gui/baculum/protected/API/Pages/API/ComponentStatus.php [new file with mode: 0644]
gui/baculum/protected/API/Pages/config.xml
gui/baculum/protected/API/endpoints.xml

diff --git a/gui/baculum/protected/API/Class/ComponentStatusModule.php b/gui/baculum/protected/API/Class/ComponentStatusModule.php
new file mode 100644 (file)
index 0000000..8b2e60d
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2018 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+Prado::using('Application.API.Class.APIModule');
+
+/**
+ * Base abstract class to inherit commonly used method
+ * in work with component status.
+ */
+abstract class ComponentStatusModule extends APIModule {
+
+       /**
+        * Method to get parsed status ready to show in API results.
+        *
+        * @param array $output array with parsed component status values
+        */
+       abstract public function getStatus(array $output);
+
+       /**
+        * Parse single component status line to find key=value pairs.
+        *
+        * @param string $line single line from component status
+        * @return mixed array with key and value on success, otherwise null
+        */
+       protected function parseLine($line) {
+               $ret = null;
+               if (preg_match('/^(?P<key>\w+)=(?P<value>[\S\s]*)$/', $line, $match) === 1) {
+                       $ret = $match;
+               }
+               return $ret;
+       }
+}
+?>
diff --git a/gui/baculum/protected/API/Class/DirectorStatus.php b/gui/baculum/protected/API/Class/DirectorStatus.php
new file mode 100644 (file)
index 0000000..b205b01
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2018 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+Prado::using('Application.API.Class.ComponentStatusModule');
+
+/**
+ * Module used to parse and prepare director status output.
+ */
+class DirectorStatus extends ComponentStatusModule {
+
+       /**
+        * Get director status by raw bconsole status director output.
+        *
+        * @param array $output bconsole status director output
+        * @return array array with parsed director status values
+        */
+       public function getStatus(array $output) {
+               $result = array();
+               $section = null;
+               $line = null;
+               $sections = array('header:', 'running:', 'terminated:');
+               $opts = array();
+               for($i = 0; $i < count($output); $i++) {
+                       if (in_array($output[$i], $sections)) { // check if section
+                               $section = rtrim($output[$i], ':');
+                       } elseif ($section === 'header' && count($opts) == 0 && $output[$i] === '') {
+                               /**
+                                * special treating 'scheduled' section because this section
+                                * is missing in the api status dir output.
+                                */
+                               $section = 'scheduled';
+                       } elseif (!empty($section)) {
+                               $line = $this->parseLine($output[$i]);
+                               if (is_array($line)) { // check if line
+                                       if (!key_exists($section, $result)) {
+                                               $result[$section] = array();
+                                               continue;
+                                       }
+                                       $opts[$line['key']] = $line['value'];
+                               } elseif (count($opts) > 0) { // dump all parameters
+                                       $result[$section][] = $opts;
+                                       $opts = array();
+                               }
+                       }
+               }
+               return $result;
+       }
+}
+?>
diff --git a/gui/baculum/protected/API/Class/StorageStatus.php b/gui/baculum/protected/API/Class/StorageStatus.php
new file mode 100644 (file)
index 0000000..4bc9c01
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2018 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+Prado::using('Application.API.Class.ComponentStatusModule');
+
+/**
+ * Module used to parse and prepare storage status output.
+ */
+class StorageStatus extends ComponentStatusModule {
+
+       /**
+        * Get director status by raw bconsole status director output.
+        *
+        * @param array $output bconsole status director output
+        * @return array array with parsed storage status values
+        */
+       public function getStatus(array $output) {
+               $result = array();
+               $line = null;
+               $opts = array();
+               $header = false;
+               for($i = 0; $i < count($output); $i++) {
+                       if (empty($output[$i])) {
+                               if  (count($opts) > 10) {
+                                       $result[] = $opts;
+                               }
+                               if (count($opts) > 0) {
+                                       $opts = array();
+                               }
+                       } elseif ($output[$i] === 'header:') {
+                               $header = true;
+                       } else {
+                               $line = $this->parseLine($output[$i]);
+                               if (is_array($line)) {
+                                       $opts[$line['key']] = $line['value'];
+                               }
+                       }
+               }
+               if ($header) {
+                       // header is only one so get it without using list
+                       $result = array_pop($result);
+               }
+               return $result;
+       }
+}
+?>
diff --git a/gui/baculum/protected/API/Pages/API/ComponentStatus.php b/gui/baculum/protected/API/Pages/API/ComponentStatus.php
new file mode 100644 (file)
index 0000000..d813cb5
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2018 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+/**
+ * Component status module.
+ */
+class ComponentStatus extends BaculumAPIServer {
+
+       public function get() {
+               $status = array();
+               $misc = $this->getModule('misc');
+               $component = $this->Request->contains('component') ? $this->Request['component'] : '';
+               $type = $this->Request->contains('type') && $misc->isValidName($this->Request['type']) ? $this->Request['type'] : '';
+
+               switch($component) {
+                       case 'director': {
+                               $result = $this->getModule('bconsole')->bconsoleCommand(
+                                       $this->director,
+                                       array('status', 'director'),
+                                       true
+                               );
+                               if ($result->exitcode === 0) {
+                                       $output = $this->getModule('status_dir')->getStatus($result->output);
+                                       if ($misc->isValidName($type) && key_exists($type, $output)) {
+                                               $this->output = $output[$type];
+                                       } else {
+                                               $this->output = $output;
+                                       }
+                               } else {
+                                       $this->output = $result->output;
+                               }
+                               $this->error = $result->exitcode;
+                               break;
+                       }
+                       case 'storage': {
+                               $storage = 'storage';
+                               if (empty($type)) {
+                                       $type = 'header'; // default list terminated jobs
+                               }
+                               if ($this->Request->contains('name') && $misc->isValidName($this->Request['name'])) {
+                                       $storage .= '="' . $this->Request['name'] . '"';
+                               }
+                               $result = $this->getModule('bconsole')->bconsoleCommand(
+                                       $this->director,
+                                       array('.status', $storage, $type),
+                                       true
+                               );
+                               if ($result->exitcode === 0) {
+                                       $this->output = $this->getModule('status_sd')->getStatus($result->output);
+                               } else {
+                                       $this->output = $result->output;
+                               }
+                               $this->error = $result->exitcode;
+                               break;
+                       }
+               }
+       }
+}
+?>
index 60e712cc00f508e72e807b2d1dcd082b931d3d75..a28dc64aa604420731923102a3aca3efd4fe3259 100644 (file)
@@ -35,5 +35,8 @@
                <module id="oauth2_config" class="Application.API.Class.OAuth2.OAuth2Config" />
                <module id="oauth2_authid" class="Application.API.Class.OAuth2.AuthIdManager" />
                <module id="oauth2_token" class="Application.API.Class.OAuth2.TokenManager" />
+               <!-- component status modules -->
+               <module id="status_dir" class="Application.API.Class.DirectorStatus" />
+               <module id="status_sd" class="Application.API.Class.StorageStatus" />
        </modules>
 </configuration>
index 0e4faa5f554b70bc150c2aa9202174881d9a6c64..6f59adcb542fedc9a8b7798abe62babc2cecde62 100644 (file)
@@ -82,6 +82,8 @@
        <url ServiceParameter="API.Config" pattern="api/v1/config/{component_type}/" parameters.component_type="[a-z]+" />
        <url ServiceParameter="API.Config" pattern="api/v1/config/{component_type}/{resource_type}/" parameters.component_type="[a-z]+" parameters.resource_type="[a-zA-Z]+" />
        <url ServiceParameter="API.Config" pattern="api/v1/config/{component_type}/{resource_type}/{resource_name}/" parameters.component_type="[a-z]+" parameters.resource_type="[a-zA-Z]+" parameters.resource_name="[a-zA-Z0-9:.\-_ ]+" />
+       <!-- component status endpoints -->
+       <url ServiceParameter="API.ComponentStatus" pattern="api/v1/status/{component}/" parameters.component="[a-z]+" />