3 * Bacula(R) - The Network Backup Solution
4 * Baculum - Bacula web interface
6 * Copyright (C) 2013-2016 Kern Sibbald
8 * The main author of Baculum is Marcin Haba.
9 * The original author of Bacula is Kern Sibbald, with contributions
10 * from many others, a complete list can be found in the file AUTHORS.
12 * You may use this file and others of this release according to the
13 * license defined in the LICENSE file, which includes the Affero General
14 * Public License, v3.0 ("AGPLv3") and some additional permissions and
15 * terms pursuant to its AGPLv3 Section 7.
17 * This notice must be preserved when any source code is
18 * conveyed and/or propagated.
20 * Bacula(R) is a registered trademark of Kern Sibbald.
23 Prado::using('Application.API.Class.APIModule');
24 Prado::using('Application.Common.Class.Errors');
27 * Bacula JSON tools manager.
29 * @author Marcin Haba <marcin.haba@bacula.pl>
31 class JSONTools extends APIModule
36 * JSON tool command pattern - standard version.
38 const JSON_TOOL_COMMAND_PATTERN = '%s%s -c %s %s 2>&1';
40 private function isJSONToolsEnabled() {
41 return $this->getModule('api_config')->isJSONToolsEnabled();
44 private function prepareOutput(array $output) {
45 $output_txt = implode('', $output);
46 $out = json_decode($output_txt, true);
47 if (!is_array($out)) {
48 $this->getModule('logging')->log('Parse output', $out, Logging::CATEGORY_EXTERNAL, __FILE__, __LINE__);
54 public function prepareResult($output, $exitcode) {
57 'exitcode' => $exitcode
62 private function getSudo($use_sudo) {
64 if ($use_sudo === true) {
65 $sudo = self::SUDO . ' ';
70 public function execCommand($component_type, $params = array(), $config = '') {
72 if ($this->isJSONToolsEnabled() === true) {
73 $tool_type = $this->getModule('bacula_setting')->getJSONToolTypeByComponentType($component_type);
74 $tool = $this->getTool($tool_type);
75 $result = $this->execTool($tool['bin'], $tool['cfg'], $tool['use_sudo'], $params, $config);
76 $output = $result['output'];
77 $exitcode = $result['exitcode'];
78 if ($exitcode === 0) {
79 $output = $this->prepareOutput($output);
80 if (is_null($output)) {
81 $output = JSONToolsError::MSG_ERROR_JSON_TOOLS_UNABLE_TO_PARSE_OUTPUT;
82 $exitcode = JSONToolsError::ERROR_JSON_TOOLS_UNABLE_TO_PARSE_OUTPUT;
85 $emsg = PHP_EOL . ' Output:' . implode(PHP_EOL, $output);
86 $output = JSONToolsError::MSG_ERROR_JSON_TOOLS_WRONG_EXITCODE . $emsg;
87 $exitcode = JSONToolsError::ERROR_JSON_TOOLS_WRONG_EXITCODE;
89 $result = $this->prepareResult($output, $exitcode);
91 $output = JSONToolsError::MSG_ERROR_JSON_TOOLS_DISABLED;
92 $exitcode = JSONToolsError::ERROR_JSON_TOOLS_DISABLED;
93 $result = $this->prepareResult($output, $exitcode);
98 private function getTool($tool_type) {
99 $tool = $this->getModule('api_config')->getJSONToolConfig($tool_type);
103 private function execTool($bin, $cfg, $use_sudo, $params = array(), $config = '') {
104 $sudo = $this->getSudo($use_sudo);
105 $options = $this->getOptions($params);
106 $cmd_pattern = $this->getCmdPattern($params);
107 if (!empty($config)) {
108 $cfg = $this->prepareConfig($config);
110 $cmd = sprintf($cmd_pattern, $sudo, $bin, $cfg, $options);
111 exec($cmd, $output, $exitcode);
112 $this->getModule('logging')->log($cmd, $output, Logging::CATEGORY_EXECUTE, __FILE__, __LINE__);
113 if (!empty($config)) {
115 if ($exitcode === 0) {
116 // @TODO: Temporary value for validation. Do it more pretty.
117 $output = array('[]');
120 $result = $this->prepareResult($output, $exitcode);
124 private function getCmdPattern($params = array()) {
125 // Default command pattern
126 return self::JSON_TOOL_COMMAND_PATTERN;
129 private function prepareConfig($config) {
130 $tool = $this->getModule('api_config')->getConfig('jsontools');
131 $fname = tempnam($tool['bconfig_dir'], 'config_');
132 file_put_contents($fname, $config);
136 private function getOptions($params = array()) {
139 if (array_key_exists('resource_type', $params)) {
140 array_push($options, '-r', $params['resource_type']);
142 if (array_key_exists('resource_name', $params)) {
143 array_push($options, '-n', $params['resource_name']);
145 if (array_key_exists('directive_name', $params) && array_key_exists('resource_type', $params)) {
146 array_push($options, '-l', $params['directive_name']);
148 if (array_key_exists('data_only', $params) && $params['data_only'] === true) {
149 array_push($options, '-D');
151 if (array_key_exists('test_config', $params) && $params['test_config'] === true) {
152 array_push($options, '-t');
154 if (array_key_exists('dont_apply_jobdefs', $params) && $params['dont_apply_jobdefs'] === true) {
155 array_push($options, '-R');
157 if (count($options) > 0) {
158 $opts = '"' . implode('" "', $options) . '"';
163 public function testJSONTool($bin, $cfg, $use_sudo) {
164 return $this->execTool($bin, $cfg, $use_sudo);