namespace Baculum\API\Modules;
-use Prado\Data\ActiveRecord\TActiveRecordCriteria;
+use Baculum\API\Modules\Database;
+use PDO;
/**
* Client manager module.
}
return $result;
}
+
+ /**
+ * Get unique client plugin list from all clients for given director.
+ *
+ * @param array $criteria SQL criteria to get job list
+ * @param bool $extended extended mode, if true it returns plugin versions too
+ * @return array unique client plugin list
+ */
+ public function getClientsPlugins($criteria, $extended = false) {
+ $plugins = [];
+ $params['Client.Plugins'] = [];
+ $params['Client.Plugins'][] = [
+ 'operator' => '!=',
+ 'vals' => ''
+ ];
+ $where = Database::getWhere($criteria);
+ $db_params = $this->getModule('api_config')->getConfig('db');
+ if ($db_params['type'] === Database::PGSQL_TYPE) {
+ $sql = '
+ SELECT
+ DISTINCT regexp_split_to_table(Plugins, \',\') AS plugins
+ FROM
+ Client
+ ' . $where['where'];
+ $statement = Database::runQuery($sql, $where['params']);
+ $result = $statement->fetchAll(PDO::FETCH_COLUMN);
+ $plugins = $result;
+ } elseif ($db_params['type'] === Database::MYSQL_TYPE) {
+ $sql = '
+ SELECT
+ Plugins AS plugins
+ FROM
+ Client
+ ' . $where['where'];
+ $statement = Database::runQuery($sql, $where['params']);
+ $result = $statement->fetchAll(PDO::FETCH_OBJ);
+ for ($i = 0; $i < count($result); $i++) {
+ $spl = explode(',', $result[$i]->plugins);
+ $plugins = array_merge($plugins, $spl);
+ }
+ }
+ $items = [];
+ for ($i = 0; $i < count($plugins); $i++) {
+ if (preg_match('/^(?P<plugin>[\w\-]+)\((?P<version>[\d\.]+)\)$/', $plugins[$i], $match) === 1) {
+ if ($extended) {
+ $items[] = [
+ 'plugin' => $match['plugin'],
+ 'version' => $match['version']
+ ];
+ } else {
+ $items[$match['plugin']] = $match['plugin'];
+ }
+ }
+ }
+ if (!$extended) {
+ $items = array_values($items);
+ sort($items);
+ }
+ return $items;
+ }
}
?>
--- /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\BaculumAPIServer;
+use Baculum\Common\Modules\Errors\ClientError;
+
+/**
+ * Plugin names endpoint.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category API
+ * @package Baculum API
+ */
+class ClientPluginNames extends BaculumAPIServer {
+ public function get() {
+ $misc = $this->getModule('misc');
+ $extended = $this->Request->contains('extended') && $misc->isValidBoolean($this->Request['extended']) ? (bool)$this->Request['extended'] : false;
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ ['.client'],
+ null,
+ true
+ );
+ if ($result->exitcode === 0) {
+ $params = [];
+ $clients = array_filter($result->output);
+ if (count($clients) == 0) {
+ // no $clients criteria means that user has no client resource assigned.
+ $this->output = [];
+ $this->error = ClientError::ERROR_NO_ERRORS;
+ return;
+ }
+
+ $params['Client.Name'] = [];
+ $params['Client.Name'][] = [
+ 'operator' => 'IN',
+ 'vals' => $clients
+ ];
+
+ $this->output = $this->getModule('client')->getClientsPlugins($params, $extended);
+ $this->error = ClientError::ERROR_NO_ERRORS;
+ } else {
+
+ $this->output = $result->output . ', Exitcode=>' . $result->exitcode;
+ $this->error = ClientError::ERROR_WRONG_EXITCODE;
+ }
+
+ }
+}
<url ServiceParameter="BasicUsers" pattern="api/v2/basic/users/" />
<url ServiceParameter="BasicUser" pattern="api/v2/basic/users/{id}/" parameters.id="[a-zA-Z0-9]+" />
<!-- Plugins -->
- <!-- M365 Plugin -->
+ <url ServiceParameter="ClientPluginNames" pattern="api/v2/plugins/client/names/" />
<url ServiceParameter="PluginCoreDirFileList" pattern="api/v2/plugins/core/{id}/storage/ls/" parameters.id="\d+" />
<url ServiceParameter="PluginCoreDiskPerf" pattern="api/v2/plugins/core/{id}/storage/diskperf/" parameters.id="\d+" />
<url ServiceParameter="PluginCoreDiskUsage" pattern="api/v2/plugins/core/{id}/storage/diskusage/" parameters.id="\d+" />
<url ServiceParameter="PluginCoreDirCreate" pattern="api/v2/plugins/core/{id}/storage/dircreate/" parameters.id="\d+" />
<url ServiceParameter="PluginCoreSCSIList" pattern="api/v2/plugins/core/{id}/storage/scsilist/" parameters.id="\d+" />
+ <!-- M365 Plugin -->
<url ServiceParameter="PluginM365ListLoggedUsers" pattern="api/v2/plugins/m365/{id}/users/" parameters.id="\d+" />
<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:.\-_ ]+" />
]
}
},
+ "/api/v2/plugins/client/names": {
+ "get": {
+ "tags": ["plugins"],
+ "summary": "Get unique client plugin list from all clients",
+ "description": "Get unique client plugin list from all clients for current director.",
+ "responses": {
+ "200": {
+ "description": "List unique client plugin list from all clients for current director",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "output": {
+ "type": "array",
+ "items": {
+ "description": "Unique client plugin list",
+ "type": "string"
+ }
+ },
+ "error": {
+ "type": "integer",
+ "description": "Error code",
+ "enum": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 1000]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "extended",
+ "in": "query",
+ "description": "Extended list with plugin versions. Note it displays multiple the same client names if version for each of them is different.",
+ "required": false,
+ "schema": {
+ "type": "boolean"
+ }
+ }
+ ]
+ }
+ },
"/api/v2/plugins/core/{storageid}/storage/ls": {
"get": {
"tags": ["plugins"],
- "summary": "List files and directories on the storage daemon host",,
+ "summary": "List files and directories on the storage daemon host",
"description": "Get list of files and directories on the storage daemon host.",
"responses": {
"200": {