]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Add VMware vSphere server list endpoint
authorMarcin Haba <marcin.haba@bacula.pl>
Tue, 14 Feb 2023 15:19:41 +0000 (16:19 +0100)
committerMarcin Haba <marcin.haba@bacula.pl>
Sun, 5 Mar 2023 06:06:30 +0000 (07:06 +0100)
gui/baculum/protected/API/Modules/ConsoleOutputQueryPage.php
gui/baculum/protected/API/Pages/API/PluginVSphereListServers.php [new file with mode: 0644]
gui/baculum/protected/API/Pages/API/endpoints.xml
gui/baculum/protected/API/openapi_baculum.json
gui/baculum/protected/Common/Modules/Errors/PluginVSphereError.php [new file with mode: 0644]

index 053647e0f0b3648e9910c2a19d10168e72a5bdb0..0c014532369786155423e90a96250fc909ddcd52 100644 (file)
@@ -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<key>\w+)=(?P<value>.*?)$/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 (file)
index 0000000..be0c084
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2023 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.
+ */
+
+use Baculum\API\Modules\ConsoleOutputPage;
+use Baculum\API\Modules\ConsoleOutputQueryPage;
+use Baculum\Common\Modules\Logging;
+use Baculum\Common\Modules\Errors\{BconsoleError,ClientError,PluginVSphereError};
+
+/**
+ * List vSphere plugin servers.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @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];
+                       }
+               }
+       }
+}
index c22cd57e5e1d3564668f2105f409698d402433f0..a63cab8138784f45b5025b921137c0fe0a21f62a 100644 (file)
        <url ServiceParameter="PluginM365ListLoggedUsers" pattern="api/v2/plugins/m365/{id}/{tenantid}/users/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
        <url ServiceParameter="PluginM365EmailList" pattern="api/v2/plugins/m365/{id}/{tenantid}/emails/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
        <url ServiceParameter="PluginM365EmailAttachmentList" pattern="api/v2/plugins/m365/{id}/{tenantid}/emails/attachments/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
+       <!-- vSphere Plugin -->
+       <url ServiceParameter="PluginVSphereListServers" pattern="api/v2/plugins/vsphere/{id}/servers" parameters.id="\d+" />
+
 
        <!-- OLD API v1 -->
        <!-- general endpoint -->
index f70c29f00817f0c93d1f28ff268b6b44e62cfc6a..4730e2c5edfe3babf88d9f3de205d5b8f98312a0 100644 (file)
                                ]
                        }
                },
+               "/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 (file)
index 0000000..aeaa153
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2023 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.
+ */
+
+namespace Baculum\Common\Modules\Errors;
+
+/**
+ * Microsoft vSphere plugin error class.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Errors
+ * @package Baculum Common
+ */
+class PluginVSphereError extends PluginError {
+}