From: Marcin Haba Date: Tue, 14 Feb 2023 15:19:41 +0000 (+0100) Subject: baculum: Add VMware vSphere server list endpoint X-Git-Tag: Release-13.0.3~132 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f535a7680f85c3952f4b3a0b1ea48b68cc8c234;p=thirdparty%2Fbacula.git baculum: Add VMware vSphere server list endpoint --- diff --git a/gui/baculum/protected/API/Modules/ConsoleOutputQueryPage.php b/gui/baculum/protected/API/Modules/ConsoleOutputQueryPage.php index 053647e0f..0c0145323 100644 --- a/gui/baculum/protected/API/Modules/ConsoleOutputQueryPage.php +++ b/gui/baculum/protected/API/Modules/ConsoleOutputQueryPage.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2022 Kern Sibbald + * Copyright (C) 2013-2023 Kern Sibbald * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -41,7 +41,22 @@ abstract class ConsoleOutputQueryPage extends ConsoleOutputPage { $ret = []; for ($i = 0; $i < count($output); $i++) { if (preg_match('/(?P\w+)=(?P.*?)$/i', $output[$i], $matches) === 1) { - $ret[$matches['key']] = $matches['value']; + if (key_exists($matches['key'], $ret)) { + // more items with the same key + if (!is_array($ret[$matches['key']])) { + // create array of items + $ret[$matches['key']] = [ + $ret[$matches['key']], // original item + $matches['value'] // new item + ]; + } else { + // add item to existing array + $ret[$matches['key']][] = $matches['value']; + } + } else { + // single key item + $ret[$matches['key']] = $matches['value']; + } } } return $ret; diff --git a/gui/baculum/protected/API/Pages/API/PluginVSphereListServers.php b/gui/baculum/protected/API/Pages/API/PluginVSphereListServers.php new file mode 100644 index 000000000..be0c08425 --- /dev/null +++ b/gui/baculum/protected/API/Pages/API/PluginVSphereListServers.php @@ -0,0 +1,144 @@ + + * @category API + * @package Baculum API + */ +class PluginVSphereListServers extends ConsoleOutputQueryPage { + + public function get() { + $client = null; + $clientid = $this->Request->contains('id') ? (int)$this->Request['id'] : 0; + $result = $this->getModule('bconsole')->bconsoleCommand( + $this->director, + ['.client'], + null, + true + ); + if ($result->exitcode === 0) { + $client_val = $this->getModule('client')->getClientById($clientid); + if (is_object($client_val) && in_array($client_val->name, $result->output)) { + $client = $client_val->name; + } else { + $this->output = ClientError::MSG_ERROR_CLIENT_DOES_NOT_EXISTS; + $this->error = ClientError::ERROR_CLIENT_DOES_NOT_EXISTS; + return; + } + } else { + $this->output = PluginVSphereError::MSG_ERROR_WRONG_EXITCODE; + $this->error = PluginVSphereError::ERROR_WRONG_EXITCODE; + return; + } + + $out_format = ConsoleOutputPage::OUTPUT_FORMAT_RAW; + if ($this->Request->contains('output') && $this->isOutputFormatValid($this->Request['output'])) { + $out_format = $this->Request['output']; + } + + $plugin = 'vsphere: '; + $out = new \StdClass; + $out->output = []; + $params = ['client' => $client, 'plugin' => $plugin]; + if ($out_format === ConsoleOutputPage::OUTPUT_FORMAT_RAW) { + $out = $this->getRawOutput($params); + } elseif($out_format === ConsoleOutputPage::OUTPUT_FORMAT_JSON) { + $out = $this->getJSONOutput($params); + } + + if ($out->exitcode !== 0) { + $out->error = PluginVSphereError::ERROR_EXECUTING_PLUGIN_QUERY_COMMAND; + $out->output = PluginVSphereError::MSG_ERROR_EXECUTING_PLUGIN_QUERY_COMMAND . $out->output; + $this->getModule('logging')->log( + Logging::CATEGORY_EXECUTE, + $out->output . ", Error={$out->error}" + ); + } else { + $out->error = BconsoleError::ERROR_NO_ERRORS; + } + $this->output = $out->output; + $this->error = $out->error; + } + + /** + * Get vSphere server list output from console in raw format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getRawOutput($params = []) { + $ret = $this->getModule('bconsole')->bconsoleCommand( + $this->director, + [ + '.query', + 'plugin="' . $params['plugin'] . '"', + 'client="' . $params['client'] . '"', + 'parameter="server"' + ] + ); + if ($ret->exitcode != 0) { + $this->getModule('logging')->log( + Logging::CATEGORY_EXECUTE, + 'Wrong output from vSphere RAW server list: ' . implode(PHP_EOL, $ret->output) + ); + $ret->output = []; // don't provide errors to output, only in logs + } + return $ret; + } + + /** + * Get vSphere server list output from console 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 = iterator_to_array($this->getServerRows($result->output)); + $result->output = $this->parseOutputKeyValue($result->output); + } + return $result; + } + + /** + * Filter rows with server items. + * + * @param array $output dot query command output + * @return none + */ + private function getServerRows(array $output) { + for ($i = 0; $i < count($output); $i++) { + if (preg_match('/^server=/', $output[$i]) === 1) { + yield $output[$i]; + } + } + } +} diff --git a/gui/baculum/protected/API/Pages/API/endpoints.xml b/gui/baculum/protected/API/Pages/API/endpoints.xml index c22cd57e5..a63cab813 100644 --- a/gui/baculum/protected/API/Pages/API/endpoints.xml +++ b/gui/baculum/protected/API/Pages/API/endpoints.xml @@ -139,6 +139,9 @@ + + + diff --git a/gui/baculum/protected/API/openapi_baculum.json b/gui/baculum/protected/API/openapi_baculum.json index f70c29f00..4730e2c5e 100644 --- a/gui/baculum/protected/API/openapi_baculum.json +++ b/gui/baculum/protected/API/openapi_baculum.json @@ -8178,6 +8178,50 @@ ] } }, + "/api/v2/plugins/vsphere/{clientid}/servers": { + "get": { + "tags": ["plugins"], + "summary": "VMware vSphere server list", + "description": "VMware vSphere server list.", + "responses": { + "200": { + "description": "List of VMware vSphere servers", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "output": { + "type": "object", + "properties": { + "server": { + "type": "array", + "description": "VMware vSphere server list. Note, server property is returned only if there exists at least one server. ", + "items": { + "description": "VMware vSphere server", + "type": "string" + } + } + } + }, + "error": { + "type": "integer", + "description": "Error code", + "enum": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 150, 1000] + } + } + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/ClientId" + } + ] + } + }, "/api/v2/search": { "get": { "tags": ["tools"], diff --git a/gui/baculum/protected/Common/Modules/Errors/PluginVSphereError.php b/gui/baculum/protected/Common/Modules/Errors/PluginVSphereError.php new file mode 100644 index 000000000..aeaa15311 --- /dev/null +++ b/gui/baculum/protected/Common/Modules/Errors/PluginVSphereError.php @@ -0,0 +1,33 @@ + + * @category Errors + * @package Baculum Common + */ +class PluginVSphereError extends PluginError { +}