]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add client plugin list endpoint
authorMarcin Haba <marcin.haba@bacula.pl>
Fri, 22 Dec 2023 14:27:39 +0000 (15:27 +0100)
committerMarcin Haba <marcin.haba@bacula.pl>
Thu, 18 Jan 2024 09:22:37 +0000 (10:22 +0100)
gui/baculum/protected/API/Modules/ClientManager.php
gui/baculum/protected/API/Pages/API/ClientPluginNames.php [new file with mode: 0644]
gui/baculum/protected/API/Pages/API/endpoints.xml
gui/baculum/protected/API/openapi_baculum.json

index be5e2d7eabe9e8a988c48b0908dc7ab6c049684f..1265fa9873a8246d5c8257dd61b81ef59900159a 100644 (file)
@@ -22,7 +22,8 @@
 
 namespace Baculum\API\Modules;
 
-use Prado\Data\ActiveRecord\TActiveRecordCriteria;
+use Baculum\API\Modules\Database;
+use PDO;
 
 /**
  * Client manager module.
@@ -171,5 +172,65 @@ FROM
                }
                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;
+       }
 }
 ?>
diff --git a/gui/baculum/protected/API/Pages/API/ClientPluginNames.php b/gui/baculum/protected/API/Pages/API/ClientPluginNames.php
new file mode 100644 (file)
index 0000000..0eabc5a
--- /dev/null
@@ -0,0 +1,68 @@
+<?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;
+               }
+
+       }
+}
index 007a897720fdacbd695c6d0a7d25770910afa6e9..00a6e90269f42790685ed41dc6385a04f542924c 100644 (file)
        <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:.\-_ ]+" />
index 69541a70f5f0e006ecddec55dec882e3a4601142..184dcbeb388a9b76173dadf5a0f1198a0c4a8bee 100644 (file)
                                ]
                        }
                },
+               "/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": {