]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Add endpoint to list m365 jobs by email
authorMarcin Haba <marcin.haba@bacula.pl>
Wed, 29 Mar 2023 13:50:26 +0000 (15:50 +0200)
committerMarcin Haba <marcin.haba@bacula.pl>
Thu, 20 Apr 2023 10:00:26 +0000 (12:00 +0200)
gui/baculum/protected/API/Modules/PluginM365Manager.php [new file with mode: 0644]
gui/baculum/protected/API/Pages/API/PluginM365EmailJobList.php [new file with mode: 0644]
gui/baculum/protected/API/Pages/API/config.xml
gui/baculum/protected/API/Pages/API/endpoints.xml
gui/baculum/protected/API/openapi_baculum.json
gui/baculum/protected/Common/Modules/Errors/PluginM365Error.php

diff --git a/gui/baculum/protected/API/Modules/PluginM365Manager.php b/gui/baculum/protected/API/Modules/PluginM365Manager.php
new file mode 100644 (file)
index 0000000..a6aaa77
--- /dev/null
@@ -0,0 +1,91 @@
+<?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\API\Modules;
+
+use PDO;
+
+/**
+ * Microsoft 365 plugin manager module.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Module
+ * @package Baculum API
+ */
+class PluginM365Manager extends APIModule {
+
+       /**
+        * Get Microsoft 365 jobs by tenant and email owner.
+        *
+        * @param string $tenant tenant name
+        * @param string $owner email owner
+        * @param array $criteria SQL criteria
+        * @return array job list or empty array if no job found
+        */
+       public function getJobsByTenantAndOwner($tenant, $owner, $criteria = []) {
+               $params = count($criteria) > 0 ? $criteria : [];
+
+               // email owner
+               $params['MetaEmail.EmailOwner'] = [];
+               $params['MetaEmail.EmailOwner'][] = [
+                       'operator' => 'AND',
+                       'vals' => [$owner]
+               ];
+
+               // email tenant
+               $params['MetaEmail.EmailTenant'] = [];
+               $params['MetaEmail.EmailTenant'][] = [
+                       'operator' => 'AND',
+                       'vals' => [$tenant]
+               ];
+
+               // job types
+               $params['Job.Type'] = [];
+               $params['Job.Type'][] = [
+                       'operator' => 'IN',
+                       'vals' => ['B']
+               ];
+
+               // job status
+               $params['Job.JobStatus'] = [];
+               $params['Job.JobStatus'][] = [
+                       'operator' => 'IN',
+                       'vals' => ['T', 'f', 'E', 'A', 'e']
+               ];
+
+               $where = Database::getWhere($params);
+
+               $sql = 'SELECT DISTINCT Job.JobId     AS jobid,
+                                       Job.Name      AS name,
+                                       Job.StartTime AS starttime,
+                                       Job.EndTime   AS endtime,
+                                       Job.JobFiles  AS jobfiles,
+                                       Job.JobBytes  AS jobbytes
+                       FROM Job
+                       LEFT JOIN MetaEmail USING (JobId)
+                       ' . $where['where'] . '
+                       ORDER BY Job.EndTime DESC';
+
+               $statement = Database::runQuery($sql, $where['params']);
+               return $statement->fetchAll(PDO::FETCH_OBJ);
+       }
+}
diff --git a/gui/baculum/protected/API/Pages/API/PluginM365EmailJobList.php b/gui/baculum/protected/API/Pages/API/PluginM365EmailJobList.php
new file mode 100644 (file)
index 0000000..3e9572f
--- /dev/null
@@ -0,0 +1,99 @@
+<?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\Common\Modules\Errors\ClientError;
+use Baculum\Common\Modules\Errors\PluginError;
+use Baculum\Common\Modules\Errors\PluginM365Error;
+
+/**
+ * Microsoft 365 plugin email job list endpoint.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category API
+ * @package Baculum API
+ */
+class PluginM365EmailJobList extends BaculumAPIServer {
+
+       public function get() {
+               $misc = $this->getModule('misc');
+               $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 = PluginError::MSG_ERROR_WRONG_EXITCODE;
+                       $this->error = PluginError::ERROR_WRONG_EXITCODE;
+                       return;
+               }
+               $tenantid = $this->Request->contains('tenantid') ? $this->Request['tenantid'] : '';
+               $fd_plugin_cfg = $this->getModule('fd_plugin_cfg')->getConfig('m365', $client, $tenantid);
+               if (!empty($tenantid) && (!$misc->isValidUUID($tenantid) || count($fd_plugin_cfg) == 0)) {
+                       $this->output = PluginM365Error::MSG_ERROR_TENANT_DOES_NOT_EXISTS;
+                       $this->error = PluginM365Error::ERROR_TENANT_DOES_NOT_EXISTS;
+                       return;
+               }
+               $tenant = $fd_plugin_cfg['tenant_name'];
+               $emailowner = $this->Request->contains('emailowner') && $misc->isValidNameExt($this->Request['emailowner']) ? $this->Request['emailowner'] : '';
+               if (empty($emailowner)) {
+                       $this->output = PluginM365Error::MSG_ERROR_EMAIL_DOES_NOT_EXISTS;
+                       $this->error = PluginM365Error::ERROR_EMAIL_DOES_NOT_EXISTS;
+                       return;
+               }
+
+               $result = $this->getModule('bconsole')->bconsoleCommand(
+                       $this->director,
+                       ['.jobs'],
+                       null,
+                       true
+               );
+               if ($result->exitcode === 0) {
+                       $params['Job.Name'] = [];
+                       $params['Job.Name'][] = [
+                               'operator' => 'OR',
+                               'vals' => $result->output
+                       ];
+                       $result = $this->getModule('m365')->getJobsByTenantAndOwner(
+                               $tenant,
+                               $emailowner,
+                               $params
+                       );
+                       $this->output = $result;
+                       $this->error = PluginM365Error::ERROR_NO_ERRORS;
+               } else {
+                       $this->output = PluginM365Error::MSG_ERROR_WRONG_EXITCODE . ', Error => ' . $result->exitcode . ' Output => ' . implode(PHP_EOL, $result->output);
+                       $this->error = PluginM365Error::ERROR_WRONG_EXITCODE;
+               }
+       }
+}
index bc367f08031a0b0e5dbd27fd41b1b96baa833281..ffdfe6c3c85c763f5a2b0f317827c5a23f4c52c7 100644 (file)
@@ -59,5 +59,7 @@
                <module id="changer_command" class="Baculum\API\Modules\ChangerCommand" />
                <!-- plugin modules -->
                <module id="fd_plugin_cfg" class="Baculum\API\Modules\PluginFDConfig" />
+               <!-- M365 modules -->
+               <module id="m365" class="Baculum\API\Modules\PluginM365Manager" />
        </modules>
 </configuration>
index 32cd4160280f18b8a66dc50f27e38a73bcbdd770..82400e8bfd61bc438b044b08b1b6e86dff7de7fc 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:.\-_ ]+" />
+       <url ServiceParameter="PluginM365EmailJobList" pattern="api/v2/plugins/m365/{id}/{tenantid}/jobs/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
        <!-- vSphere Plugin -->
        <url ServiceParameter="PluginVSphereListServers" pattern="api/v2/plugins/vsphere/{id}/servers" parameters.id="\d+" />
        <url ServiceParameter="PluginVSphereListHosts" pattern="api/v2/plugins/vsphere/{id}/hosts" parameters.id="\d+" />
index 2796d0db64d635a66bca546060a2a10f02d881df..3101901be92eb3cc97e7b77e21ec4905b1c4a8f6 100644 (file)
                                ]
                        }
                },
+               "/api/v2/plugins/m365/{clientid}/{tenantid}/jobs": {
+                       "get": {
+                               "tags": ["plugins"],
+                               "summary": "Microsoft 365 plugin job list for specific email account.",
+                               "description": "Get Microsoft 365 plugin job list for specific email account.",
+                               "responses": {
+                                       "200": {
+                                               "description": "List of Microsoft 365 jobs for given email",
+                                               "content": {
+                                                       "application/json": {
+                                                               "schema": {
+                                                                       "type": "object",
+                                                                       "properties": {
+                                                                               "output": {
+                                                                                       "type": "array",
+                                                                                       "items": {
+                                                                                               "type": "object",
+                                                                                               "properties": {
+                                                                                                       "jobid": {
+                                                                                                               "type": "integer",
+                                                                                                               "description": "Job identifier"
+                                                                                                       },
+                                                                                                       "name": {
+                                                                                                               "type": "string",
+                                                                                                               "description": "Job name"
+                                                                                                       },
+                                                                                                       "starttime": {
+                                                                                                               "type": "string",
+                                                                                                               "description": "Start time"
+                                                                                                       },
+                                                                                                       "endtime": {
+                                                                                                               "type": "string",
+                                                                                                               "description": "Start time"
+                                                                                                       },
+                                                                                                       "jobfiles": {
+                                                                                                               "type": "integer",
+                                                                                                               "description": "Job files"
+                                                                                                       },
+                                                                                                       "jobbytes": {
+                                                                                                               "type": "integer",
+                                                                                                               "description": "Job bytes"
+                                                                                                       }
+                                                                                               }
+                                                                                       }
+                                                                               },
+                                                                               "error": {
+                                                                                       "type": "integer",
+                                                                                       "description": "Error code",
+                                                                                       "enum": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 160, 161, 1000]
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+                               "parameters": [
+                                       {
+                                               "$ref": "#/components/parameters/ClientId"
+                                       },
+                                       {
+                                               "$ref": "#/components/parameters/TenantId"
+                                       },
+                                       {
+                                               "name": "emailowner",
+                                               "in": "query",
+                                               "required": true,
+                                               "description": "Email to get jobs",
+                                               "schema": {
+                                                       "type": "string"
+                                               }
+                                       }
+                               ]
+                       }
+               },
                "/api/v2/plugins/vsphere/{clientid}/servers": {
                        "get": {
                                "tags": ["plugins"],
index 9b3f1edf050321a5006c388d91b285e2273e3976..508f2afc80678782c9307102ea4c2ebb39374d12 100644 (file)
@@ -31,6 +31,8 @@ namespace Baculum\Common\Modules\Errors;
  */
 class PluginM365Error extends PluginError {
        const ERROR_TENANT_DOES_NOT_EXISTS = 160;
+       const ERROR_EMAIL_DOES_NOT_EXISTS = 161;
 
        const MSG_ERROR_TENANT_DOES_NOT_EXISTS = 'Tenant does not exist.';
+       const MSG_ERROR_EMAIL_DOES_NOT_EXISTS = 'Email does not exist.';
 }