WIP
This commit is contained in:
parent
42f1a9ff34
commit
7bcef8edf9
@ -4,6 +4,7 @@ const { setSetting, setting } = require("./util-server");
|
|||||||
const { log, sleep } = require("../src/util");
|
const { log, sleep } = require("../src/util");
|
||||||
const dayjs = require("dayjs");
|
const dayjs = require("dayjs");
|
||||||
const knex = require("knex");
|
const knex = require("knex");
|
||||||
|
const { PluginsManager } = require("./plugins-manager");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database & App Data Folder
|
* Database & App Data Folder
|
||||||
@ -83,6 +84,13 @@ class Database {
|
|||||||
static init(args) {
|
static init(args) {
|
||||||
// Data Directory (must be end with "/")
|
// Data Directory (must be end with "/")
|
||||||
Database.dataDir = process.env.DATA_DIR || args["data-dir"] || "./data/";
|
Database.dataDir = process.env.DATA_DIR || args["data-dir"] || "./data/";
|
||||||
|
|
||||||
|
// Plugin feature is working only if the dataDir = "./data";
|
||||||
|
if (Database.dataDir !== "./data/") {
|
||||||
|
log.warn("PLUGIN", "Warning: In order to enable plugin feature, you need to use the default data directory: ./data/");
|
||||||
|
PluginsManager.disable = true;
|
||||||
|
}
|
||||||
|
|
||||||
Database.path = Database.dataDir + "kuma.db";
|
Database.path = Database.dataDir + "kuma.db";
|
||||||
if (! fs.existsSync(Database.dataDir)) {
|
if (! fs.existsSync(Database.dataDir)) {
|
||||||
fs.mkdirSync(Database.dataDir, { recursive: true });
|
fs.mkdirSync(Database.dataDir, { recursive: true });
|
||||||
|
@ -617,6 +617,15 @@ class Monitor extends BeanModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bean.ping = dayjs().valueOf() - startTime;
|
bean.ping = dayjs().valueOf() - startTime;
|
||||||
|
|
||||||
|
} else if (this.type in UptimeKumaServer.monitorTypeList) {
|
||||||
|
let startTime = dayjs().valueOf();
|
||||||
|
const monitorType = UptimeKumaServer.monitorTypeList[this.type];
|
||||||
|
await monitorType.check(this, bean);
|
||||||
|
if (!bean.ping) {
|
||||||
|
bean.ping = dayjs().valueOf() - startTime;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bean.msg = "Unknown Monitor Type";
|
bean.msg = "Unknown Monitor Type";
|
||||||
bean.status = PENDING;
|
bean.status = PENDING;
|
||||||
|
@ -1,5 +1,19 @@
|
|||||||
class MonitorType {
|
class MonitorType {
|
||||||
|
|
||||||
|
name = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Monitor} monitor
|
||||||
|
* @param {Heartbeat} heartbeat
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async check(monitor, heartbeat) {
|
||||||
|
throw new Error("You need to override check()");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = MonitorType;
|
module.exports = {
|
||||||
|
MonitorType,
|
||||||
|
};
|
||||||
|
13
server/plugin.js
Normal file
13
server/plugin.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
class Plugin {
|
||||||
|
async install() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async uninstall() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
Plugin,
|
||||||
|
};
|
@ -4,9 +4,11 @@ const path = require("path");
|
|||||||
|
|
||||||
class PluginsManager {
|
class PluginsManager {
|
||||||
|
|
||||||
|
static disable = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin List
|
* Plugin List
|
||||||
* @type {Plugin[]}
|
* @type {PluginWrapper[]}
|
||||||
*/
|
*/
|
||||||
pluginList = [];
|
pluginList = [];
|
||||||
|
|
||||||
@ -20,8 +22,9 @@ class PluginsManager {
|
|||||||
* @param {UptimeKumaServer} server
|
* @param {UptimeKumaServer} server
|
||||||
* @param {string} dir
|
* @param {string} dir
|
||||||
*/
|
*/
|
||||||
constructor(server, dir) {
|
constructor(server) {
|
||||||
this.pluginsDir = dir;
|
if (!PluginsManager.disable) {
|
||||||
|
this.pluginsDir = "./data/plugins/";
|
||||||
|
|
||||||
if (! fs.existsSync(this.pluginsDir)) {
|
if (! fs.existsSync(this.pluginsDir)) {
|
||||||
fs.mkdirSync(this.pluginsDir, { recursive: true });
|
fs.mkdirSync(this.pluginsDir, { recursive: true });
|
||||||
@ -32,7 +35,7 @@ class PluginsManager {
|
|||||||
|
|
||||||
this.pluginList = [];
|
this.pluginList = [];
|
||||||
for (let item of list) {
|
for (let item of list) {
|
||||||
let plugin = new Plugin(server, this.pluginsDir + item);
|
let plugin = new PluginWrapper(server, this.pluginsDir + item);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
plugin.load();
|
plugin.load();
|
||||||
@ -42,6 +45,11 @@ class PluginsManager {
|
|||||||
log.error("plugin", "Reason: " + e.message);
|
log.error("plugin", "Reason: " + e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.warn("PLUGIN", "Skip scanning plugin directory");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,7 +79,7 @@ class PluginsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Plugin {
|
class PluginWrapper {
|
||||||
|
|
||||||
server = undefined;
|
server = undefined;
|
||||||
pluginDir = undefined;
|
pluginDir = undefined;
|
||||||
@ -129,5 +137,5 @@ class Plugin {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
PluginsManager,
|
PluginsManager,
|
||||||
Plugin
|
PluginWrapper
|
||||||
};
|
};
|
||||||
|
@ -167,7 +167,7 @@ let needSetup = false;
|
|||||||
Database.init(args);
|
Database.init(args);
|
||||||
await initDatabase(testMode);
|
await initDatabase(testMode);
|
||||||
await server.initAfterDatabaseReady();
|
await server.initAfterDatabaseReady();
|
||||||
server.loadPlugins(Database.dataDir + "plugins/");
|
server.loadPlugins();
|
||||||
server.entryPage = await Settings.get("entryPage");
|
server.entryPage = await Settings.get("entryPage");
|
||||||
await StatusPage.loadDomainMappingList();
|
await StatusPage.loadDomainMappingList();
|
||||||
|
|
||||||
|
@ -55,6 +55,14 @@ class UptimeKumaServer {
|
|||||||
*/
|
*/
|
||||||
pluginsManager = null;
|
pluginsManager = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {{}}
|
||||||
|
*/
|
||||||
|
static monitorTypeList = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
static getInstance(args) {
|
static getInstance(args) {
|
||||||
if (UptimeKumaServer.instance == null) {
|
if (UptimeKumaServer.instance == null) {
|
||||||
UptimeKumaServer.instance = new UptimeKumaServer(args);
|
UptimeKumaServer.instance = new UptimeKumaServer(args);
|
||||||
@ -249,11 +257,34 @@ class UptimeKumaServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadPlugins(dir) {
|
loadPlugins(dir) {
|
||||||
this.pluginsManager = new PluginsManager(this, dir);
|
this.pluginsManager = new PluginsManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {MonitorType} monitorType
|
||||||
|
*/
|
||||||
addMonitorType(monitorType) {
|
addMonitorType(monitorType) {
|
||||||
// TODO
|
if (monitorType instanceof MonitorType && monitorType.name) {
|
||||||
|
if (monitorType.name in UptimeKumaServer.monitorTypeList) {
|
||||||
|
log.error("", "Conflict Monitor Type name");
|
||||||
|
}
|
||||||
|
UptimeKumaServer.monitorTypeList[monitorType.name] = monitorType;
|
||||||
|
} else {
|
||||||
|
log.error("", "Invalid Monitor Type: " + monitorType.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {MonitorType} monitorType
|
||||||
|
*/
|
||||||
|
removeMonitorType(monitorType) {
|
||||||
|
if (UptimeKumaServer.monitorTypeList[monitorType.name] === monitorType) {
|
||||||
|
delete UptimeKumaServer.monitorTypeList[monitorType.name];
|
||||||
|
} else {
|
||||||
|
log.error("", "Remove MonitorType failed: " + monitorType.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -264,3 +295,4 @@ module.exports = {
|
|||||||
|
|
||||||
// Must be at the end
|
// Must be at the end
|
||||||
const MaintenanceTimeslot = require("./model/maintenance_timeslot");
|
const MaintenanceTimeslot = require("./model/maintenance_timeslot");
|
||||||
|
const { MonitorType } = require("./monitor-types/monitor-type");
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
<optgroup :label="$t('Custom Monitor Type')">
|
<optgroup :label="$t('Custom Monitor Type')">
|
||||||
<option value="browser">
|
<option value="browser">
|
||||||
HTTP(s) with Real Browsers (Chromium or Firefox)
|
(Early Access/WIP) HTTP(s) (Browser Engine)
|
||||||
</option>
|
</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</select>
|
</select>
|
||||||
@ -77,7 +77,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- URL -->
|
<!-- URL -->
|
||||||
<div v-if="monitor.type === 'http' || monitor.type === 'keyword' " class="my-3">
|
<div v-if="monitor.type === 'http' || monitor.type === 'keyword' || monitor.type === 'browser' " class="my-3">
|
||||||
<label for="url" class="form-label">{{ $t("URL") }}</label>
|
<label for="url" class="form-label">{{ $t("URL") }}</label>
|
||||||
<input id="url" v-model="monitor.url" type="url" class="form-control" pattern="https?://.+" required>
|
<input id="url" v-model="monitor.url" type="url" class="form-control" pattern="https?://.+" required>
|
||||||
</div>
|
</div>
|
||||||
@ -99,10 +99,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Keyword -->
|
<!-- Keyword -->
|
||||||
<div v-if="monitor.type === 'keyword' || monitor.type === 'grpc-keyword' " class="my-3">
|
<div v-if="monitor.type === 'keyword' || monitor.type === 'grpc-keyword'" class="my-3">
|
||||||
<label for="keyword" class="form-label">{{ $t("Keyword") }}</label>
|
<label for="keyword" class="form-label">{{ $t("Keyword") }}</label>
|
||||||
<input id="keyword" v-model="monitor.keyword" type="text" class="form-control" required>
|
<input id="keyword" v-model="monitor.keyword" type="text" class="form-control" required>
|
||||||
<div class="form-text">
|
<div v-if="monitor.type === 'keyword' || monitor.type === 'grpc-keyword'" class="form-text">
|
||||||
{{ $t("keywordDescription") }}
|
{{ $t("keywordDescription") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
BIN
src/util.js
BIN
src/util.js
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user