--- /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\API\Modules;
+
+/**
+ * File event manager module.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Module
+ * @package Baculum API
+ */
+class FileEventManager extends APIModule {
+
+ /**
+ * Get file event list.
+ *
+ * @param array $criteria list of optional query criterias
+ * @param int $limit_val limit results value
+ * @param int $offset_val offset results value
+ */
+ public function getFileEvents($criteria = [], $limit_val = 0, $offset_val = 0) {
+ $sort_col = 'Id';
+ $db_params = $this->getModule('api_config')->getConfig('db');
+ if ($db_params['type'] === Database::PGSQL_TYPE) {
+ $sort_col = strtolower($sort_col);
+ }
+ $order = ' ORDER BY ' . $sort_col . ' DESC';
+ $limit = '';
+ if(is_int($limit_val) && $limit_val > 0) {
+ $limit = ' LIMIT ' . $limit_val;
+ }
+ $offset = '';
+ if (is_int($offset_val) && $offset_val > 0) {
+ $offset = ' OFFSET ' . $offset_val;
+ }
+
+ $where = Database::getWhere($criteria);
+
+ $sql = 'SELECT FileEvents.* FROM FileEvents ' . $where['where'] . $order . $limit . $offset;
+
+ return FileEventRecord::finder()->findAllBySql($sql, $where['params']);
+ }
+
+ /**
+ * Get single file event record by id.
+ *
+ * @param integer $id file event identifier
+ * @return FileEventRecord single file event record or null on failure
+ */
+ public function getEventById($id) {
+ $params = [
+ 'FileEvents.Id' => [[
+ 'vals' => $id,
+ ]]
+ ];
+ $obj = $this->getFileEvents($params, 1);
+ if (is_array($obj) && count($obj) > 0) {
+ $obj = array_shift($obj);
+ }
+ return $obj;
+ }
+}
--- /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\API\Modules;
+
+/**
+ * File event record module.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Database
+ * @package Baculum API
+ */
+class FileEventRecord extends APIDbModule {
+
+ const TABLE = 'FileEvents';
+
+ public $id;
+ public $time;
+ public $sourcejobid;
+ public $jobid;
+ public $fileindex;
+ public $type;
+ public $description;
+ public $severity;
+ public $source;
+
+ public static function finder($className = __CLASS__) {
+ return parent::finder($className);
+ }
+}
+?>
--- /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\Common\Modules\Errors\FileEventError;
+
+/**
+ * Event endpoint.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category API
+ * @package Baculum API
+ */
+class FileEvent extends BaculumAPIServer {
+
+ public function get() {
+ $eventid = $this->Request->contains('id') ? (int)$this->Request['id'] : 0;
+
+ $event = $this->getModule('fileevent')->getEventById($eventid);
+ if (is_object($event)) {
+ $this->output = $event;
+ $this->error = FileEventError::ERROR_NO_ERRORS;
+ } else {
+ $this->output = FileEventError::MSG_ERROR_FILE_EVENT_DOES_NOT_EXIST;
+ $this->error = FileEventError::ERROR_FILE_EVENT_DOES_NOT_EXIST;
+ }
+ }
+}
--- /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\Common\Modules\Errors\FileEventError;
+
+/**
+ * Events endpoint.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category API
+ * @package Baculum API
+ */
+class FileEvents extends BaculumAPIServer {
+
+ public function get() {
+ $misc = $this->getModule('misc');
+ $limit = $this->Request->contains('limit') ? intval($this->Request['limit']) : 0;
+ $offset = $this->Request->contains('offset') && $misc->isValidInteger($this->Request['offset']) ? (int)$this->Request['offset'] : 0;
+ $sourcejobid = $this->Request->contains('sourcejobid') && $misc->isValidInteger($this->Request['sourcejobid']) ? (int)$this->Request['sourcejobid'] : null;
+ $jobid = $this->Request->contains('jobid') && $misc->isValidInteger($this->Request['jobid']) ? (int)$this->Request['jobid'] : null;
+ $fileindex = $this->Request->contains('fileindex') && $misc->isValidInteger($this->Request['fileindex']) ? (int)$this->Request['fileindex'] : null;
+ $type = $this->Request->contains('type') && $misc->isValidName($this->Request['type']) ? $this->Request['type'] : null;
+ $severity = $this->Request->contains('severity') && $misc->isValidInteger($this->Request['severity']) ? (int)$this->Request['severity'] : null;
+ $source = $this->Request->contains('source') && $misc->isValidName($this->Request['source']) ? $this->Request['source'] : null;
+ $description = $this->Request->contains('description') && $misc->isValidNameExt($this->Request['description']) ? $this->Request['description'] : null;
+ $time_from_date = $this->Request->contains('time_from_date') && $misc->isValidBDateAndTime($this->Request['time_from_date']) ? $this->Request['time_from_date'] : null;
+ $time_to_date = $this->Request->contains('time_to_date') && $misc->isValidBDateAndTime($this->Request['time_to_date']) ? $this->Request['time_to_date'] : null;
+
+ $params = [];
+ if (!empty($jobid)) {
+ $params['FileEvents.JobId'] = [[
+ 'vals' => $jobid
+ ]];
+ }
+ if (!empty($sourcejobid)) {
+ $params['FileEvents.SourceJobId'] = [[
+ 'vals' => $sourcejobid
+ ]];
+ }
+ if (!empty($fileindex)) {
+ $params['FileEvents.FileIndex'] = [[
+ 'vals' => $fileindex
+ ]];
+ }
+ if (!empty($type)) {
+ $params['FileEvents.Type'] = [[
+ 'vals' => $type
+ ]];
+ }
+ if (!empty($severity)) {
+ $params['FileEvents.Severity'] = [[
+ 'vals' => $severity
+ ]];
+ }
+ if (!empty($source)) {
+ $params['FileEvents.Source'] = [[
+ 'vals' => $source
+ ]];
+ }
+ if (!empty($description)) {
+ $params['FileEvents.Description'] = [[
+ 'vals' => $description
+ ]];
+ }
+
+ if (!empty($time_from_date) || !empty($time_to_date)) {
+ $params['FileEvents.Time'] = [];
+ if (!empty($time_from_date)) {
+ $params['FileEvents.Time'][] = [
+ 'vals' => $time_from_date,
+ 'operator' => '>='
+ ];
+ }
+ if (!empty($time_to_date)) {
+ $params['FileEvents.Time'][] = [
+ 'vals' => $time_to_date,
+ 'operator' => '<='
+ ];
+ }
+ }
+
+ $fileevents = $this->getModule('fileevent')->getFileEvents(
+ $params,
+ $limit,
+ $offset
+ );
+ $this->output = $fileevents;
+ $this->error = FileEventError::ERROR_NO_ERRORS;
+ }
+}
<module id="volume" class="Baculum\API\Modules\VolumeManager" />
<module id="object" class="Baculum\API\Modules\ObjectManager" />
<module id="event" class="Baculum\API\Modules\EventManager" />
+ <module id="fileevent" class="Baculum\API\Modules\FileEventManager" />
<module id="source" class="Baculum\API\Modules\SourceManager" />
<!-- tools modules -->
<module id="bconsole" class="Baculum\API\Modules\Bconsole" />
<!-- event endpoints -->
<url ServiceParameter="Events" pattern="api/v2/events/" />
<url ServiceParameter="Event" pattern="api/v2/events/{id}" parameters.id="\d+" />
+ <!-- file event endpoints -->
+ <url ServiceParameter="FileEvents" pattern="api/v2/fileevents/" />
+ <url ServiceParameter="FileEvent" pattern="api/v2/fileevents/{id}" parameters.id="\d+" />
<!-- source endpoints -->
<url ServiceParameter="Sources" pattern="api/v2/sources/" />
<!-- @TODO: Separate this endpoint outside 'joblog' -->
"Event": {
"$ref": "#/definitions/Event"
},
+ "FileEvents": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/FileEvent"
+ }
+ },
+ "FileEvent": {
+ "$ref": "#/definitions/FileEvent"
+ },
"PluginM365Emails": {
"type": "array",
"items": {
]
}
},
+ "/api/v2/fileevents": {
+ "get": {
+ "tags": ["fileevents"],
+ "summary": "File event list",
+ "description": "Get file event list.",
+ "responses": {
+ "200": {
+ "description": "List of file events",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "output": {
+ "$ref": "#/components/schemas/FileEvents"
+ },
+ "error": {
+ "type": "integer",
+ "description": "Error code",
+ "enum": [0, 1, 2, 3, 6, 7, 1000]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/Limit"
+ },
+ {
+ "$ref": "#/components/parameters/Offset"
+ },
+ {
+ "name": "sourcejobid",
+ "in": "query",
+ "required": false,
+ "description": "Source job identifier",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "jobid",
+ "in": "query",
+ "required": false,
+ "description": "Job identifier",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "fileindex",
+ "in": "query",
+ "required": false,
+ "description": "File index",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "type",
+ "in": "query",
+ "required": false,
+ "description": "File event type",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "severity",
+ "in": "query",
+ "required": false,
+ "description": "File event severity",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "source",
+ "in": "query",
+ "required": false,
+ "description": "From where file event comes",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "description",
+ "in": "query",
+ "required": false,
+ "description": "File event description",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "time_from_date",
+ "in": "query",
+ "required": false,
+ "description": "File event time from (date/time format YYYY-MM-DD HH:II:SS)",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "time_to_date",
+ "in": "query",
+ "required": false,
+ "description": "File event time to (date/time format YYYY-MM-DD HH:II:SS)",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ },
+ "/api/v2/fileevents/{fileeventid}": {
+ "get": {
+ "tags": ["fileevents"],
+ "summary": "File event by id",
+ "description": "Get single file event.",
+ "responses": {
+ "200": {
+ "description": "Single file event by id",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "output": {
+ "$ref": "#/components/schemas/FileEvent"
+ },
+ "error": {
+ "type": "integer",
+ "description": "Error code",
+ "enum": [0, 1, 2, 3, 6, 7, 170, 1000]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "description": "File event identifier",
+ "schema": {
+ "type": "integer"
+ }
+ }
+ ]
+ }
+ },
"/api/v2/plugins/m365/{clientid}/tenants": {
"get": {
"tags": ["plugins"],
}
}
},
+ "FileEvent": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "File event identifier",
+ "type": "integer"
+ },
+ "time": {
+ "description": "File event time (YYYY-MM-DD HH:MM::SS.MMMMMM)",
+ "type": "string"
+ },
+ "sourcejobid": {
+ "description": "File event source job identifier",
+ "type": "integer"
+ },
+ "jobid": {
+ "description": "Job identifier",
+ "type": "integer"
+ },
+ "fileindex": {
+ "description": "File index",
+ "type": "integer"
+ },
+ "type": {
+ "description": "File event type",
+ "type": "string"
+ },
+ "description": {
+ "description": "File event description",
+ "type": "string"
+ },
+ "severity": {
+ "description": "File event severity",
+ "type": "integer"
+ },
+ "source": {
+ "description": "From where file event comes",
+ "type": "string"
+ }
+ }
+ },
"PluginM365Email": {
"type": "object",
"properties": {
--- /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;
+
+/**
+ * File event error class.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Errors
+ * @package Baculum Common
+ */
+class FileEventError extends GenericError {
+ const ERROR_FILE_EVENT_DOES_NOT_EXIST = 170;
+
+ const MSG_ERROR_FILE_EVENT_DOES_NOT_EXIST = 'File event does not exist.';
+}