From: Marcin Haba Date: Thu, 21 Sep 2023 08:21:47 +0000 (+0200) Subject: baculum: Add endpoint to list files and dirs on storage daemon host X-Git-Tag: Beta-15.0.0~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a0a7376cfe842a0cb20528e782ddffbb33662df5;p=thirdparty%2Fbacula.git baculum: Add endpoint to list files and dirs on storage daemon host --- diff --git a/gui/baculum/protected/API/Pages/API/PluginCoreDirFileList.php b/gui/baculum/protected/API/Pages/API/PluginCoreDirFileList.php new file mode 100644 index 000000000..13c0bc5cb --- /dev/null +++ b/gui/baculum/protected/API/Pages/API/PluginCoreDirFileList.php @@ -0,0 +1,161 @@ + + * @category API + * @package Baculum API + */ +class PluginCoreDirFileList extends ConsoleOutputQueryPage { + + public function get() { + $misc = $this->getModule('misc'); + $storageid = $this->Request->contains('id') && $misc->isValidInteger($this->Request['id']) ? (int)$this->Request['id'] : 0; + $path = $this->Request->contains('path') && $misc->isValidPath($this->Request['path']) ? $this->Request['path'] : ''; + $dironly = $this->Request->contains('dironly') && $misc->isValidBoolean($this->Request['dironly']) ? (bool)$this->Request['dironly'] : false; + $result = $this->getModule('bconsole')->bconsoleCommand( + $this->director, + ['.storage'], + null, + true + ); + if ($result->exitcode === 0) { + $storage_val = $this->getModule('storage')->getStorageById($storageid); + if (is_object($storage_val) && in_array($storage_val->name, $result->output)) { + $storage = $storage_val->name; + } else { + $this->output = StorageError::MSG_ERROR_STORAGE_DOES_NOT_EXISTS; + $this->error = StorageError::ERROR_STORAGE_DOES_NOT_EXISTS; + return; + } + } else { + $this->output = PluginError::MSG_ERROR_WRONG_EXITCODE; + $this->error = PluginError::ERROR_WRONG_EXITCODE; + return; + } + $params = [ + 'storage' => $storage, + 'path' => $path, + 'dironly' => $dironly + ]; + + + $out_format = ConsoleOutputPage::OUTPUT_FORMAT_RAW; + if ($this->Request->contains('output') && $this->isOutputFormatValid($this->Request['output'])) { + $out_format = $this->Request['output']; + } + + $out = new \StdClass; + $out->output = []; + if ($out_format === ConsoleOutputPage::OUTPUT_FORMAT_RAW) { + $out = $this->getRawOutput($params); + } elseif($out_format === ConsoleOutputPage::OUTPUT_FORMAT_JSON) { + $out = $this->getJSONOutput($params); + } + $this->output = $out->output; + if ($out->exitcode != PluginError::ERROR_EXECUTING_PLUGIN_QUERY_COMMAND) { + if ($out->exitcode != 0) { + $this->error = PluginError::ERROR_WRONG_EXITCODE; + $this->output = PluginError::MSG_ERROR_WRONG_EXITCODE; + } else { + $this->error = PluginError::ERROR_NO_ERRORS; + } + } + } + + /** + * Get query dirlist command output in raw format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getRawOutput($params = []) { + $extra = ($params['dironly'] ? ' opt=d' : ''); + $ret = $this->getModule('bconsole')->bconsoleCommand( + $this->director, + [ + '.query', + 'plugin="core: dirname=\"' . $params['path'] . '\"' . $extra . '"', + 'storage="' . $params['storage'] . '"', + 'parameter="dirlist"' + ], + null, + true + ); + if ($ret->exitcode != 0) { + $this->getModule('logging')->log( + Logging::CATEGORY_EXECUTE, + 'Wrong output from RAW .query dirlist: ' . implode(PHP_EOL, $ret->output) + ); + $ret->output = []; // don't provide errors to output, only in logs + } elseif ($this->isError($ret->output)) { + $ret->exitcode = PluginError::ERROR_EXECUTING_PLUGIN_QUERY_COMMAND; + } + return $ret; + } + + /** + * Get query dirlist command output in JSON format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getJSONOutput($params = []) { + $result = $this->getRawOutput($params); + if ($result->exitcode === 0) { + $result->output = $this->getItemRows($result->output); + } + return $result; + } + + /** + * Parse and get rows with items from output. + * + * @param array $output dot query command output + * @return array parsed output + */ + private function getItemRows(array $output) { + $out = []; + $tmp = []; + $found = false; + for ($i = 0; $i < count($output); $i++) { + if (preg_match('/^filename=/', $output[$i]) === 1 || $found == true) { + $tmp[] = $output[$i]; + $found = !empty($output[$i]); + } + if (!$found && count($tmp) > 0) { + $out[] = $this->parseOutputKeyValue($tmp); + $tmp = []; + } + } + return $out; + } +} diff --git a/gui/baculum/protected/API/Pages/API/endpoints.xml b/gui/baculum/protected/API/Pages/API/endpoints.xml index f799cfe71..379293b6d 100644 --- a/gui/baculum/protected/API/Pages/API/endpoints.xml +++ b/gui/baculum/protected/API/Pages/API/endpoints.xml @@ -149,6 +149,7 @@ + diff --git a/gui/baculum/protected/API/openapi_baculum.json b/gui/baculum/protected/API/openapi_baculum.json index baa61b546..4b87ec432 100644 --- a/gui/baculum/protected/API/openapi_baculum.json +++ b/gui/baculum/protected/API/openapi_baculum.json @@ -10005,6 +10005,65 @@ ] } }, + "/api/v2/plugins/core/{storageid}/storage/ls": { + "get": { + "tags": ["plugins"], + "summary": "List files and directories on the storage daemon host",, + "description": "Get list of files and directories on the storage daemon host.", + "responses": { + "200": { + "description": "List of files and directories on the storage daemon host", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "output": { + "type": "array", + "items": { + "description": "File and directory list with properties", + "type": "string" + } + }, + "error": { + "type": "integer", + "description": "Error code", + "enum": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 20, 150, 1000] + } + } + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/StorageId" + }, + { + "name": "path", + "in": "query", + "description": "Path to list files and directories", + "required": false, + "schema": { + "type": "string" + } + }, + { + "$ref": "#/components/parameters/Output" + }, + { + "name": "dironly", + "in": "query", + "description": "If true, in output are listed directories only", + "required": false, + "schema": { + "type": "boolean" + } + } + ] + } + }, "/api/v2/plugins/m365/{clientid}/tenants": { "get": { "tags": ["plugins"],