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