--- /dev/null
+<?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;
+ }
+}
+?>
--- /dev/null
+<?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;
+ }
+}
+?>
--- /dev/null
+<?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;
+ }
+}
+?>
--- /dev/null
+<?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;
+ }
+ }
+ }
+}
+?>
<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>
<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]+" />