[int]
This commit is contained in:
parent
bcc0283149
commit
27d6b4eb16
45
lib/plankton/plankton.d.ts
vendored
45
lib/plankton/plankton.d.ts
vendored
|
|
@ -1487,6 +1487,9 @@ declare namespace lib_plankton.file {
|
|||
* @author fenris
|
||||
*/
|
||||
function write_buffer(path: string, content: Buffer, options?: {}): Promise<void>;
|
||||
/**
|
||||
*/
|
||||
function delete_(path: string): Promise<void>;
|
||||
}
|
||||
declare namespace lib_plankton.translate {
|
||||
/**
|
||||
|
|
@ -1905,3 +1908,45 @@ declare namespace lib_plankton.http {
|
|||
decode(x: string): type_response;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.sqlite {
|
||||
/**
|
||||
*/
|
||||
type type_query_raw = {
|
||||
template: string;
|
||||
arguments: Record<string, any>;
|
||||
};
|
||||
/**
|
||||
*/
|
||||
type type_connection = {
|
||||
handle: any;
|
||||
};
|
||||
/**
|
||||
*/
|
||||
function get_connection(database_path: string): Promise<type_connection>;
|
||||
/**
|
||||
*/
|
||||
function drop_connection(connection: type_connection): Promise<void>;
|
||||
/**
|
||||
* for CREATE TABLE, DROP TABLE, etc.
|
||||
*/
|
||||
function query_set(connection: type_connection, query_raw: type_query_raw): Promise<any>;
|
||||
/**
|
||||
* for INSERT, UPDATE, DELETE
|
||||
*/
|
||||
function query_put(connection: type_connection, query_raw: type_query_raw): Promise<{
|
||||
id: (null | number);
|
||||
affected: (null | number);
|
||||
}>;
|
||||
/**
|
||||
* for SELECT
|
||||
*
|
||||
* @todo rather use handle procedure for rows instead of returning an array
|
||||
*/
|
||||
function query_get(connection: type_connection, query_raw: type_query_raw): Promise<Array<Record<string, any>>>;
|
||||
/**
|
||||
* for SELECT
|
||||
*
|
||||
* @todo rather use handle procedure for rows instead of returning an array
|
||||
*/
|
||||
function query_probe(connection: type_connection, query_raw: type_query_raw, handler: ((row: Record<string, any>) => void)): void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4274,7 +4274,7 @@ var lib_plankton;
|
|||
return (new Promise(function (resolve, reject) {
|
||||
nm_fs.readFile(path, {
|
||||
"encoding": "utf8",
|
||||
"flag": "r",
|
||||
"flag": "r"
|
||||
}, function (error, content) {
|
||||
if (error == null) {
|
||||
resolve(content);
|
||||
|
|
@ -4293,7 +4293,7 @@ var lib_plankton;
|
|||
var nm_fs = require("fs");
|
||||
return (new Promise(function (resolve, reject) {
|
||||
nm_fs.readFile(path, {
|
||||
"flag": "r",
|
||||
"flag": "r"
|
||||
}, function (error, content) {
|
||||
if (error == null) {
|
||||
resolve(content);
|
||||
|
|
@ -4330,13 +4330,13 @@ var lib_plankton;
|
|||
function write(path, content, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
options = Object.assign({
|
||||
"encoding": "utf-8",
|
||||
"encoding": "utf-8"
|
||||
}, options);
|
||||
var nm_fs = require("fs");
|
||||
return (new Promise(function (resolve, reject) {
|
||||
nm_fs.writeFile(path, content, {
|
||||
"encoding": options.encoding,
|
||||
"flag": "w",
|
||||
"flag": "w"
|
||||
}, function (error) {
|
||||
if (error == null) {
|
||||
resolve(undefined);
|
||||
|
|
@ -4357,7 +4357,7 @@ var lib_plankton;
|
|||
var nm_fs = require("fs");
|
||||
return (new Promise(function (resolve, reject) {
|
||||
nm_fs.writeFile(path, content, {
|
||||
"flag": "w",
|
||||
"flag": "w"
|
||||
}, function (error) {
|
||||
if (error == null) {
|
||||
resolve(undefined);
|
||||
|
|
@ -4369,6 +4369,17 @@ var lib_plankton;
|
|||
}));
|
||||
}
|
||||
file.write_buffer = write_buffer;
|
||||
/**
|
||||
*/
|
||||
function delete_(path) {
|
||||
var nm_fs = require("fs");
|
||||
return (new Promise(function (resolve, reject) {
|
||||
nm_fs.unlink(path, function () {
|
||||
resolve(undefined);
|
||||
});
|
||||
}));
|
||||
}
|
||||
file.delete_ = delete_;
|
||||
})(file = lib_plankton.file || (lib_plankton.file = {}));
|
||||
})(lib_plankton || (lib_plankton = {}));
|
||||
/*
|
||||
|
|
@ -4851,8 +4862,8 @@ var lib_plankton;
|
|||
"info": info,
|
||||
"hidden": hidden,
|
||||
"parameters": {
|
||||
"index": index,
|
||||
},
|
||||
"index": index
|
||||
}
|
||||
}));
|
||||
};
|
||||
/**
|
||||
|
|
@ -4870,8 +4881,8 @@ var lib_plankton;
|
|||
"hidden": hidden,
|
||||
"parameters": {
|
||||
"indicators_short": indicators_short,
|
||||
"indicators_long": indicators_long,
|
||||
},
|
||||
"indicators_long": indicators_long
|
||||
}
|
||||
}));
|
||||
};
|
||||
/**
|
||||
|
|
@ -5117,17 +5128,17 @@ var lib_plankton;
|
|||
"symbols": {
|
||||
"delimiter": " ",
|
||||
"prefix": "--",
|
||||
"assignment": "=",
|
||||
},
|
||||
"assignment": "="
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"symbols": {
|
||||
"delimiter": "&",
|
||||
"prefix": "",
|
||||
"assignment": "=",
|
||||
"assignment": "="
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @author fenris
|
||||
|
|
@ -5204,14 +5215,14 @@ var lib_plankton;
|
|||
"pattern_from": pattern_from,
|
||||
"pattern_to": pattern_to,
|
||||
"input": input,
|
||||
"result": result,
|
||||
"result": result
|
||||
});
|
||||
input = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
lib_plankton.log.debug("lib_args:read:current_input", {
|
||||
"input": input,
|
||||
"input": input
|
||||
});
|
||||
}
|
||||
// parsing
|
||||
|
|
@ -5222,18 +5233,18 @@ var lib_plankton;
|
|||
var index_expected_1 = 0;
|
||||
parts.forEach(function (part) {
|
||||
lib_plankton.log.debug("lib_args:read:analyzing", {
|
||||
"part": part,
|
||||
"part": part
|
||||
});
|
||||
var found = [
|
||||
function () {
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile", {
|
||||
"part": part,
|
||||
"part": part
|
||||
});
|
||||
for (var _i = 0, _a = Object.entries(_this.filter(args.enum_kind.volatile)); _i < _a.length; _i++) {
|
||||
var _b = _a[_i], name = _b[0], argument = _b[1];
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", {
|
||||
"part": part,
|
||||
"argument": argument.toString(),
|
||||
"argument": argument.toString()
|
||||
});
|
||||
var pattern = "";
|
||||
{
|
||||
|
|
@ -5252,12 +5263,12 @@ var lib_plankton;
|
|||
pattern += pattern_back;
|
||||
}
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", {
|
||||
"pattern": pattern,
|
||||
"pattern": pattern
|
||||
});
|
||||
var regexp = new RegExp(pattern);
|
||||
var matching = regexp.exec(part);
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", {
|
||||
"matching": matching,
|
||||
"matching": matching
|
||||
});
|
||||
if (matching == null) {
|
||||
// do nothing
|
||||
|
|
@ -5271,7 +5282,7 @@ var lib_plankton;
|
|||
},
|
||||
function () {
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_positional", {
|
||||
"part": part,
|
||||
"part": part
|
||||
});
|
||||
var positional = _this.filter(args.enum_kind.positional);
|
||||
for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) {
|
||||
|
|
@ -5282,7 +5293,7 @@ var lib_plankton;
|
|||
else {
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", {
|
||||
"part": part,
|
||||
"argument": argument.toString(),
|
||||
"argument": argument.toString()
|
||||
});
|
||||
var pattern = "";
|
||||
{
|
||||
|
|
@ -5291,12 +5302,12 @@ var lib_plankton;
|
|||
pattern += pattern_back;
|
||||
}
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", {
|
||||
"pattern": pattern,
|
||||
"pattern": pattern
|
||||
});
|
||||
var regexp = new RegExp(pattern);
|
||||
var matching = regexp.exec(part);
|
||||
lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", {
|
||||
"matching": matching,
|
||||
"matching": matching
|
||||
});
|
||||
if (matching == null) {
|
||||
return false;
|
||||
|
|
@ -5313,7 +5324,7 @@ var lib_plankton;
|
|||
].some(function (x) { return x(); });
|
||||
if (!found) {
|
||||
lib_plankton.log.warning("lib_args:read:could_not_parse", {
|
||||
"part": part,
|
||||
"part": part
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -5831,7 +5842,7 @@ var lib_plankton;
|
|||
((request.query === null)
|
||||
? ""
|
||||
: request.query));
|
||||
// console.info({target,options});
|
||||
console.info({ target });
|
||||
switch (options.implementation) {
|
||||
default: {
|
||||
return Promise.reject("invalid implementation: " + options.implementation);
|
||||
|
|
@ -6019,3 +6030,145 @@ var lib_plankton;
|
|||
http.class_http_response = class_http_response;
|
||||
})(http = lib_plankton.http || (lib_plankton.http = {}));
|
||||
})(lib_plankton || (lib_plankton = {}));
|
||||
/*
|
||||
This file is part of »bacterio-plankton:sqlite«.
|
||||
|
||||
Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
|
||||
<info@greenscale.de>
|
||||
|
||||
»bacterio-plankton:sqlite« is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
»bacterio-plankton:sqlite« is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with »bacterio-plankton:sqlite«. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
var lib_plankton;
|
||||
(function (lib_plankton) {
|
||||
var sqlite;
|
||||
(function (sqlite) {
|
||||
/**
|
||||
*/
|
||||
function get_connection(database_path) {
|
||||
return (new Promise((resolve, reject) => {
|
||||
const nm_sqlite3 = require("sqlite3");
|
||||
const handle = new nm_sqlite3.Database(database_path, (nm_sqlite3.OPEN_READWRITE
|
||||
|
|
||||
nm_sqlite3.OPEN_CREATE
|
||||
|
|
||||
nm_sqlite3.OPEN_FULLMUTEX), (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve({
|
||||
"handle": handle,
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
sqlite.get_connection = get_connection;
|
||||
/**
|
||||
*/
|
||||
function drop_connection(connection) {
|
||||
return (new Promise((resolve, reject) => {
|
||||
connection.handle.close(() => {
|
||||
resolve(undefined);
|
||||
});
|
||||
}));
|
||||
}
|
||||
sqlite.drop_connection = drop_connection;
|
||||
/**
|
||||
*/
|
||||
function query_transform(query_raw) {
|
||||
return {
|
||||
"template": query_raw.template,
|
||||
"arguments": Object.fromEntries(Object.entries(query_raw.arguments)
|
||||
.map(([key, value]) => ([(":" + key), value]))),
|
||||
};
|
||||
}
|
||||
/**
|
||||
* for CREATE TABLE, DROP TABLE, etc.
|
||||
*/
|
||||
async function query_set(connection, query_raw) {
|
||||
const query_transformed = query_transform(query_raw);
|
||||
return (new Promise((resolve, reject) => {
|
||||
connection.handle.run(query_transformed.template, query_transformed.arguments, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
sqlite.query_set = query_set;
|
||||
/**
|
||||
* for INSERT, UPDATE, DELETE
|
||||
*/
|
||||
async function query_put(connection, query_raw) {
|
||||
const query_transformed = query_transform(query_raw);
|
||||
return (new Promise((resolve, reject) => {
|
||||
connection.handle.run(query_transformed.template, query_transformed.arguments,
|
||||
// must be a classic function due the special use of "this"
|
||||
function (error) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve({
|
||||
"id": this.lastID,
|
||||
"affected": this.changes,
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
sqlite.query_put = query_put;
|
||||
/**
|
||||
* for SELECT
|
||||
*
|
||||
* @todo rather use handle procedure for rows instead of returning an array
|
||||
*/
|
||||
async function query_get(connection, query_raw) {
|
||||
const query_transformed = query_transform(query_raw);
|
||||
return (new Promise((resolve, reject) => {
|
||||
connection.handle.all(query_transformed.template, query_transformed.arguments, (error, rows) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve(rows);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
sqlite.query_get = query_get;
|
||||
/**
|
||||
* for SELECT
|
||||
*
|
||||
* @todo rather use handle procedure for rows instead of returning an array
|
||||
*/
|
||||
function query_probe(connection, query_raw, handler) {
|
||||
const query_transformed = query_transform(query_raw);
|
||||
connection.handle.each(query_transformed.template, query_transformed.arguments, function (error, row) {
|
||||
if (error) {
|
||||
// do nothing
|
||||
// log?
|
||||
}
|
||||
else {
|
||||
handler(row);
|
||||
}
|
||||
});
|
||||
}
|
||||
sqlite.query_probe = query_probe;
|
||||
})(sqlite = lib_plankton.sqlite || (lib_plankton.sqlite = {}));
|
||||
})(lib_plankton || (lib_plankton = {}));
|
||||
|
|
|
|||
288
source/app/cli.ts
Normal file
288
source/app/cli.ts
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/**
|
||||
*/
|
||||
async function main(
|
||||
) : Promise<void>
|
||||
{
|
||||
await _heimdall.init();
|
||||
|
||||
// consts
|
||||
const version : string = "0.9";
|
||||
|
||||
// args
|
||||
const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler(
|
||||
{
|
||||
"order_path": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "order_path",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.positional,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": "monitoring.hmdl.json",
|
||||
"parameters": {
|
||||
"index": 0,
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.order_path"),
|
||||
}
|
||||
),
|
||||
"show_help": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "help",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["help"],
|
||||
"indicators_short": ["h"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.show_help"),
|
||||
}
|
||||
),
|
||||
"show_version": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "version",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["version"],
|
||||
"indicators_short": ["r"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.show_version"),
|
||||
}
|
||||
),
|
||||
"show_schema": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "schema",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["schema"],
|
||||
"indicators_short": ["s"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.show_schema"),
|
||||
}
|
||||
),
|
||||
"expose_full_order": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "expose_full_order",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["expose-full-order"],
|
||||
"indicators_short": ["e"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.expose_full_order"),
|
||||
}
|
||||
),
|
||||
"erase_state": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "erase_state",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["erase-state"],
|
||||
"indicators_short": ["x"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.erase_state"),
|
||||
}
|
||||
),
|
||||
"database_path": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "database_path",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": null,
|
||||
"parameters": {
|
||||
"indicators_long": ["database-path"],
|
||||
"indicators_short": ["d"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.database_path"),
|
||||
}
|
||||
),
|
||||
"mutex_path": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "mutex_path",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": "/tmp/heimdall.lock",
|
||||
"parameters": {
|
||||
"indicators_long": ["mutex-path"],
|
||||
"indicators_short": ["m"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.mutex_path"),
|
||||
}
|
||||
),
|
||||
"send_ok_notifications": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "send_ok_notifications",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["send-ok-notifications"],
|
||||
"indicators_short": ["y"],
|
||||
},
|
||||
"info": lib_plankton.translate.get(
|
||||
"help.args.send_ok_notifications",
|
||||
{
|
||||
"condition_name": lib_plankton.translate.get("conditions.ok"),
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
"language": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "language",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": null,
|
||||
"parameters": {
|
||||
"indicators_long": ["language"],
|
||||
"indicators_short": ["l"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.language"),
|
||||
}
|
||||
),
|
||||
"time_to_live": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "time_to_live",
|
||||
"type": lib_plankton.args.enum_type.float,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": (60 * 60 * 24 * 7),
|
||||
"parameters": {
|
||||
"indicators_long": ["time-to-live"],
|
||||
"indicators_short": ["t"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.time_to_live"),
|
||||
}
|
||||
),
|
||||
"verbosity": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "verbosity",
|
||||
"type": lib_plankton.args.enum_type.integer,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": 1,
|
||||
"parameters": {
|
||||
"indicators_long": ["verbosity"],
|
||||
"indicators_short": ["v"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.verbosity"),
|
||||
}
|
||||
),
|
||||
}
|
||||
);
|
||||
const args : Record<string, any> = arg_handler.read(
|
||||
lib_plankton.args.enum_environment.cli,
|
||||
process.argv.slice(2).join(" ")
|
||||
);
|
||||
|
||||
// setup logging
|
||||
lib_plankton.log.conf_push(
|
||||
[
|
||||
new lib_plankton.log.class_channel_minlevel(
|
||||
new lib_plankton.log.class_channel_stdout(),
|
||||
[
|
||||
lib_plankton.log.enum_level.debug,
|
||||
lib_plankton.log.enum_level.info,
|
||||
lib_plankton.log.enum_level.notice,
|
||||
lib_plankton.log.enum_level.warning,
|
||||
lib_plankton.log.enum_level.error,
|
||||
][Math.min(4, args["verbosity"])]
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
// exec
|
||||
if (args.show_help) {
|
||||
process.stdout.write(
|
||||
arg_handler.generate_help(
|
||||
{
|
||||
"programname": "heimdall",
|
||||
"description": lib_plankton.translate.get("help.title"),
|
||||
"executable": "heimdall",
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
if (args["show_version"]) {
|
||||
process.stdout.write(version + "\n");
|
||||
}
|
||||
else {
|
||||
if (args["show_schema"]) {
|
||||
process.stdout.write(
|
||||
lib_plankton.json.encode(
|
||||
_heimdall.order.schema_root(
|
||||
),
|
||||
true
|
||||
)
|
||||
+
|
||||
"\n"
|
||||
)
|
||||
}
|
||||
else {
|
||||
const nm_path = require("path");
|
||||
const nm_fs = require("fs");
|
||||
if (! nm_fs.existsSync(args["order_path"])) {
|
||||
lib_plankton.log.error(
|
||||
lib_plankton.translate.get("misc.order_file_not_found"),
|
||||
{
|
||||
"path": args["order_path"],
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
const order : _heimdall.type_order = await _heimdall.order.load(
|
||||
nm_path.normalize(args["order_path"])
|
||||
);
|
||||
if (args["expose_full_order"]) {
|
||||
process.stdout.write(lib_plankton.json.encode(order, true) + "\n");
|
||||
}
|
||||
else {
|
||||
await _heimdall.master.wrap_mutex(
|
||||
args["mutex_path"],
|
||||
() => _heimdall.master.wrap_database(
|
||||
args["database_path"],
|
||||
args["order_path"],
|
||||
async () => {
|
||||
await _heimdall.master.clean(
|
||||
{
|
||||
"time_to_live": args["time_to_live"],
|
||||
"erase_state": args["erase_state"],
|
||||
}
|
||||
);
|
||||
await _heimdall.master.run(
|
||||
order,
|
||||
{
|
||||
"send_ok_notifications": args["send_ok_notifications"],
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
)
|
||||
.catch(
|
||||
() => {process.exit(2);}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
main();
|
||||
|
|
@ -1,6 +1,17 @@
|
|||
namespace _heimdall.helpers.misc
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export function get_env_language(
|
||||
) : (null | string)
|
||||
{
|
||||
const env_lang : string = process.env["LANG"];
|
||||
const locale : string = env_lang.split(".")[0];
|
||||
const language : string = locale.split("_")[0];
|
||||
return language;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
export function format_bytes(
|
||||
49
source/init.ts
Normal file
49
source/init.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
namespace _heimdall
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function init(
|
||||
) : Promise<void>
|
||||
{
|
||||
const workdir : string = __dirname;
|
||||
|
||||
// translation
|
||||
{
|
||||
const language_order : Array<string> = ["de", "en"];
|
||||
await lib_plankton.translate.initialize_promise(
|
||||
{
|
||||
"verbosity": 1,
|
||||
"order": language_order,
|
||||
"packages": await Promise.all(
|
||||
[
|
||||
{"identifier": "de", "path": (workdir + "/localization/de.json")},
|
||||
{"identifier": "en", "path": (workdir + "/localization/en.json")},
|
||||
]
|
||||
.map(
|
||||
(entry) => (
|
||||
lib_plankton.file.read(entry.path)
|
||||
.then(content => Promise.resolve(JSON.parse(content)))
|
||||
.then(tree => Promise.resolve({"meta": {"identifier": entry.identifier}, "tree": tree}))
|
||||
)
|
||||
)
|
||||
),
|
||||
}
|
||||
);
|
||||
const env_language : (null | string) = _heimdall.helpers.misc.get_env_language();
|
||||
if (
|
||||
! (
|
||||
(env_language !== null)
|
||||
&&
|
||||
language_order.includes(env_language)
|
||||
)
|
||||
) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
lib_plankton.translate.promote(env_language);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -37,5 +37,5 @@
|
|||
"misc.check_procedure_failed": "Prüfungs-Prozedur fehlgeschlagen",
|
||||
"misc.still_running": "läuft bereits/noch",
|
||||
"misc.cleanup_info": "{{count}} alte Ergebnis-Datensätze gelöscht",
|
||||
"misc.order_file_not_found": "Auftrags-Datei nicht gefunden: {{path}}"
|
||||
"misc.order_file_not_found": "Auftrags-Datei nicht gefunden"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,5 +37,5 @@
|
|||
"misc.check_procedure_failed": "check procedure failed",
|
||||
"misc.still_running": "already/still running",
|
||||
"misc.cleanup_info": "removed {{count}} old result entries",
|
||||
"misc.order_file_not_found": "order file not found: {{path}}"
|
||||
"misc.order_file_not_found": "order file not found"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
namespace _heimdall.check_kinds
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export type type_check_kind = {
|
||||
parameters_schema : (() => _heimdall.helpers.json_schema.type_schema);
|
||||
normalize_order_node : ((node : any) => any);
|
||||
run : (parameters) => Promise<_heimdall.type_result>;
|
||||
};
|
||||
|
||||
}
|
||||
59
source/logic/check_kinds/_base.ts
Normal file
59
source/logic/check_kinds/_base.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
namespace _heimdall.check_kinds
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export type type_check_kind = {
|
||||
parameters_schema : (
|
||||
()
|
||||
=>
|
||||
_heimdall.helpers.json_schema.type_schema
|
||||
);
|
||||
normalize_order_node : (
|
||||
(node : any)
|
||||
=>
|
||||
any
|
||||
);
|
||||
run : (
|
||||
(parameters)
|
||||
=>
|
||||
Promise<_heimdall.type_result>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
var _implementations : Record<string, type_check_kind> = {};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_implementation(
|
||||
name : string,
|
||||
check_kind : type_check_kind
|
||||
) : void
|
||||
{
|
||||
_implementations[name] = check_kind;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function get_implementation(
|
||||
name : string
|
||||
) : type_check_kind
|
||||
{
|
||||
return _implementations[name];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function get_implementations(
|
||||
) : Record<string, type_check_kind>
|
||||
{
|
||||
return _implementations;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -366,14 +366,13 @@ namespace _heimdall.check_kinds.file_state
|
|||
|
||||
/**
|
||||
*/
|
||||
export function check_kind_implementation(
|
||||
) : type_check_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"file_state",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"run": run,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,14 +242,13 @@ namespace _heimdall.check_kinds.generic_remote
|
|||
|
||||
/**
|
||||
*/
|
||||
export function check_kind_implementation(
|
||||
) : type_check_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"generic_remote",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"run": run,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -380,14 +380,13 @@ namespace _heimdall.check_kinds.http_request
|
|||
|
||||
/**
|
||||
*/
|
||||
export function check_kind_implementation(
|
||||
) : type_check_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"http_request",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"run": run,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,14 +118,13 @@ namespace _heimdall.check_kinds.script
|
|||
|
||||
/**
|
||||
*/
|
||||
export function check_kind_implementation(
|
||||
) : type_check_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"script",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"run": run,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,14 +237,13 @@ namespace _heimdall.check_kinds.tls_certificate
|
|||
|
||||
/**
|
||||
*/
|
||||
export function check_kind_implementation(
|
||||
) : type_check_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"tls_certificate",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"run": run,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,176 +0,0 @@
|
|||
namespace _heimdall.helpers.sqlite
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export type type_query_raw = {
|
||||
template : string;
|
||||
arguments : Record<string, any>;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_query_transformed = {
|
||||
template : string;
|
||||
arguments : Record<string, any>;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
function query_transform(
|
||||
query_raw : type_query_raw
|
||||
) : type_query_transformed
|
||||
{
|
||||
return {
|
||||
"template": query_raw.template,
|
||||
"arguments": lib_plankton.call.convey(
|
||||
query_raw.arguments,
|
||||
[
|
||||
x => Object.entries(x),
|
||||
x => (
|
||||
x.map(
|
||||
([key, value]) => ([
|
||||
(":" + key),
|
||||
value
|
||||
])
|
||||
)
|
||||
),
|
||||
x => Object.fromEntries(x),
|
||||
]
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
function execute(
|
||||
database_path : string,
|
||||
action : ((handle) => Promise<void>),
|
||||
) : Promise<void>
|
||||
{
|
||||
return (
|
||||
new Promise<void>(
|
||||
async (resolve, reject) => {
|
||||
const nm_sqlite3 = require("sqlite3");
|
||||
const handle = new nm_sqlite3.Database(database_path);
|
||||
try {
|
||||
await action(handle);
|
||||
handle.close();
|
||||
resolve(undefined);
|
||||
}
|
||||
catch (error) {
|
||||
handle.close();
|
||||
reject(error);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* for CREATE TABLE, DROP TABLE, etc.
|
||||
*/
|
||||
export async function query_set(
|
||||
database_path : string,
|
||||
query_raw : type_query_raw
|
||||
) : Promise<any>
|
||||
{
|
||||
const query_transformed : type_query_transformed = query_transform(query_raw);
|
||||
await execute(
|
||||
database_path,
|
||||
(handle) => new Promise<void>(
|
||||
(resolve, reject) => {
|
||||
handle.run(
|
||||
query_transformed.template,
|
||||
query_transformed.arguments,
|
||||
(error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve(undefined);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* for INSERT, UPDATE, DELETE
|
||||
*/
|
||||
export async function query_put(
|
||||
database_path : string,
|
||||
query_raw : type_query_raw
|
||||
) : Promise<{id : (null | int); affected : (null | int);}>
|
||||
{
|
||||
let result : {id : (null | int); affected : (null | int);};
|
||||
const query_transformed : type_query_transformed = query_transform(query_raw);
|
||||
await execute(
|
||||
database_path,
|
||||
(handle) => new Promise<void>(
|
||||
(resolve, reject) => {
|
||||
handle.run(
|
||||
query_transformed.template,
|
||||
query_transformed.arguments,
|
||||
function (error) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
result = {
|
||||
"id": this.lastID,
|
||||
"affected": this.changes,
|
||||
};
|
||||
resolve(undefined);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* for SELECT
|
||||
*/
|
||||
export async function query_get(
|
||||
database_path : string,
|
||||
query_raw : type_query_raw
|
||||
) : Promise<Array<Array<any>>>
|
||||
{
|
||||
const query_transformed : type_query_transformed = query_transform(query_raw);
|
||||
let rows : Array<Array<any>> = [];
|
||||
await execute(
|
||||
database_path,
|
||||
(handle) => new Promise<void>(
|
||||
(resolve, reject) => {
|
||||
handle.all(
|
||||
query_transformed.template,
|
||||
query_transformed.arguments,
|
||||
(error, row) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
rows.push(row);
|
||||
resolve(undefined);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
return rows;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,569 +0,0 @@
|
|||
async function main(
|
||||
) : Promise<void>
|
||||
{
|
||||
// consts
|
||||
const version : string = "0.9";
|
||||
const workdir : string = __dirname;
|
||||
|
||||
// init translations
|
||||
// TODO: use env language
|
||||
await lib_plankton.translate.initialize_promise(
|
||||
{
|
||||
"verbosity": 1,
|
||||
"order": ["de", "en"],
|
||||
"packages": await Promise.all(
|
||||
[
|
||||
{"identifier": "de", "path": (workdir + "/localization/de.json")},
|
||||
{"identifier": "en", "path": (workdir + "/localization/en.json")},
|
||||
]
|
||||
.map(
|
||||
(entry) => (
|
||||
lib_plankton.file.read(entry.path)
|
||||
.then(content => Promise.resolve(JSON.parse(content)))
|
||||
.then(tree => Promise.resolve({"meta": {"identifier": entry.identifier}, "tree": tree}))
|
||||
)
|
||||
)
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
// args
|
||||
const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler(
|
||||
{
|
||||
"order_path": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "order_path",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.positional,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": "monitoring.hmdl.json",
|
||||
"parameters": {
|
||||
"index": 0,
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.order_path"),
|
||||
}
|
||||
),
|
||||
"show_help": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "help",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["help"],
|
||||
"indicators_short": ["h"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.show_help"),
|
||||
}
|
||||
),
|
||||
"show_version": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "version",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["version"],
|
||||
"indicators_short": ["r"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.show_version"),
|
||||
}
|
||||
),
|
||||
"show_schema": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "schema",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["schema"],
|
||||
"indicators_short": ["s"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.show_schema"),
|
||||
}
|
||||
),
|
||||
"expose_full_order": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "expose_full_order",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["expose-full-order"],
|
||||
"indicators_short": ["e"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.expose_full_order"),
|
||||
}
|
||||
),
|
||||
"erase_state": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "erase_state",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["erase-state"],
|
||||
"indicators_short": ["x"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.erase_state"),
|
||||
}
|
||||
),
|
||||
"database_path": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "database_path",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": null,
|
||||
"parameters": {
|
||||
"indicators_long": ["database-path"],
|
||||
"indicators_short": ["d"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.database_path"),
|
||||
}
|
||||
),
|
||||
"mutex_path": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "mutex_path",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": "/tmp/heimdall.lock",
|
||||
"parameters": {
|
||||
"indicators_long": ["mutex-path"],
|
||||
"indicators_short": ["m"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.mutex_path"),
|
||||
}
|
||||
),
|
||||
"send_ok_notifications": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "send_ok_notifications",
|
||||
"type": lib_plankton.args.enum_type.boolean,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": false,
|
||||
"parameters": {
|
||||
"indicators_long": ["send-ok-notifications"],
|
||||
"indicators_short": ["y"],
|
||||
},
|
||||
"info": lib_plankton.translate.get(
|
||||
"help.args.send_ok_notifications",
|
||||
{
|
||||
"condition_name": lib_plankton.translate.get("conditions.ok"),
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
"language": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "language",
|
||||
"type": lib_plankton.args.enum_type.string,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": null,
|
||||
"parameters": {
|
||||
"indicators_long": ["language"],
|
||||
"indicators_short": ["l"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.language"),
|
||||
}
|
||||
),
|
||||
"time_to_live": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "time_to_live",
|
||||
"type": lib_plankton.args.enum_type.float,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": (60 * 60 * 24 * 7),
|
||||
"parameters": {
|
||||
"indicators_long": ["time-to-live"],
|
||||
"indicators_short": ["t"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.time_to_live"),
|
||||
}
|
||||
),
|
||||
"verbosity": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "verbosity",
|
||||
"type": lib_plankton.args.enum_type.integer,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": 1,
|
||||
"parameters": {
|
||||
"indicators_long": ["verbosity"],
|
||||
"indicators_short": ["v"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.verbosity"),
|
||||
}
|
||||
),
|
||||
}
|
||||
);
|
||||
const args : Record<string, any> = arg_handler.read(
|
||||
lib_plankton.args.enum_environment.cli,
|
||||
process.argv.slice(2).join(" ")
|
||||
);
|
||||
|
||||
// setup logging
|
||||
lib_plankton.log.conf_push(
|
||||
[
|
||||
new lib_plankton.log.class_channel_minlevel(
|
||||
new lib_plankton.log.class_channel_stdout(),
|
||||
[
|
||||
lib_plankton.log.enum_level.debug,
|
||||
lib_plankton.log.enum_level.info,
|
||||
lib_plankton.log.enum_level.notice,
|
||||
lib_plankton.log.enum_level.warning,
|
||||
lib_plankton.log.enum_level.error,
|
||||
][Math.min(4, args["verbosity"])]
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
// exec
|
||||
if (args.show_help) {
|
||||
process.stdout.write(
|
||||
arg_handler.generate_help(
|
||||
{
|
||||
"programname": "heimdall",
|
||||
"description": lib_plankton.translate.get("help.title"),
|
||||
"executable": "heimdall",
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
if (args["show_version"]) {
|
||||
process.stdout.write(version + "\n");
|
||||
}
|
||||
else {
|
||||
const notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind> = {
|
||||
"console": _heimdall.notification_kinds.console.notification_kind_implementation(),
|
||||
"email": _heimdall.notification_kinds.email.notification_kind_implementation(),
|
||||
"libnotify": _heimdall.notification_kinds.libnotify.notification_kind_implementation(),
|
||||
};
|
||||
const check_kind_implementations : Record<string, _heimdall.check_kinds.type_check_kind> = {
|
||||
"script": _heimdall.check_kinds.script.check_kind_implementation(),
|
||||
"http_request": _heimdall.check_kinds.http_request.check_kind_implementation(),
|
||||
"file_state": _heimdall.check_kinds.file_state.check_kind_implementation(),
|
||||
"tls_certificate": _heimdall.check_kinds.tls_certificate.check_kind_implementation(),
|
||||
"generic_remote": _heimdall.check_kinds.generic_remote.check_kind_implementation(),
|
||||
};
|
||||
if (args["show_schema"]) {
|
||||
process.stdout.write(
|
||||
lib_plankton.json.encode(
|
||||
_heimdall.order.schema_root(
|
||||
check_kind_implementations,
|
||||
notification_kind_implementations
|
||||
),
|
||||
true
|
||||
)
|
||||
+
|
||||
"\n"
|
||||
)
|
||||
}
|
||||
else {
|
||||
const nm_path = require("path");
|
||||
const nm_fs = require("fs");
|
||||
if (! nm_fs.existsSync(args["order_path"])) {
|
||||
process.stderr.write(
|
||||
lib_plankton.translate.get(
|
||||
"misc.order_file_not_found",
|
||||
{
|
||||
"path": args["order_path"],
|
||||
}
|
||||
)
|
||||
+
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
else {
|
||||
// get order data
|
||||
const order = await _heimdall.order.load(
|
||||
check_kind_implementations,
|
||||
notification_kind_implementations,
|
||||
nm_path.normalize(args["order_path"])
|
||||
);
|
||||
|
||||
if (args["expose_full_order"]) {
|
||||
process.stdout.write(lib_plankton.json.encode(order, true) + "\n");
|
||||
}
|
||||
else {
|
||||
const database_path : string = (
|
||||
(args["database_path"] !== null)
|
||||
? args["database_path"]
|
||||
: nm_path.join(
|
||||
// TODO get path from fs or path module?
|
||||
"/tmp",
|
||||
lib_plankton.string.coin(
|
||||
"monitoring-state-{{id}}.sqlite",
|
||||
{
|
||||
"id": lib_plankton.call.convey(
|
||||
args["order_path"],
|
||||
[
|
||||
nm_path.normalize,
|
||||
// encode(ascii),
|
||||
x => lib_plankton.sha256.get(x),
|
||||
x => x.slice(0, 8),
|
||||
]
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
lib_plankton.log.info(
|
||||
lib_plankton.translate.get("misc.state_file_path"),
|
||||
{
|
||||
"database_path": database_path,
|
||||
}
|
||||
);
|
||||
|
||||
// mutex check
|
||||
if (nm_fs.existsSync(args["mutex_path"])) {
|
||||
lib_plankton.log.error(
|
||||
lib_plankton.translate.get("misc.still_running"),
|
||||
{
|
||||
"mutex_path": args["mutex_path"],
|
||||
}
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
else {
|
||||
await _heimdall.state_repository.setup(database_path);
|
||||
const clean_count : int = await _heimdall.state_repository.clean(
|
||||
database_path,
|
||||
args["time_to_live"],
|
||||
args["erase_state"]
|
||||
);
|
||||
|
||||
// create mutex file
|
||||
await lib_plankton.file.write(args["mutex_path"], "");
|
||||
|
||||
for await (const check of order.checks) {
|
||||
if (! check.active) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
let old_item_state : (null | _heimdall.type_item_state);
|
||||
|
||||
const last_notification_timestamp : (null | int) = await _heimdall.state_repository.get_last_notification_timestamp(
|
||||
database_path,
|
||||
check.name
|
||||
);
|
||||
|
||||
const rows : Array<
|
||||
{
|
||||
timestamp : int;
|
||||
condition : _heimdall.enum_condition;
|
||||
notification_sent : boolean;
|
||||
}
|
||||
> = await _heimdall.state_repository.probe(
|
||||
database_path,
|
||||
check.name,
|
||||
(check.threshold + 1),
|
||||
);
|
||||
if (rows.length <= 0) {
|
||||
old_item_state = null;
|
||||
}
|
||||
else {
|
||||
let count : int = 1;
|
||||
rows.slice(1).some(
|
||||
(row) => {
|
||||
if (row.condition === rows[0].condition) {
|
||||
count += 1;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
if (count > check.threshold) {
|
||||
count = null;
|
||||
}
|
||||
else {
|
||||
// do nothing
|
||||
}
|
||||
old_item_state = {
|
||||
"timestamp": rows[0].timestamp,
|
||||
"condition": rows[0].condition,
|
||||
"count": count,
|
||||
"last_notification_timestamp": last_notification_timestamp,
|
||||
}
|
||||
|
||||
const timestamp : int = _heimdall.get_current_timestamp();
|
||||
const due : boolean = (
|
||||
(old_item_state === null)
|
||||
||
|
||||
(old_item_state.condition !== _heimdall.enum_condition.ok)
|
||||
||
|
||||
((timestamp - old_item_state.timestamp) >= check.schedule.regular_interval)
|
||||
||
|
||||
(
|
||||
(! (old_item_state.count === null))
|
||||
&&
|
||||
((timestamp - old_item_state.timestamp) >= check.schedule.attentive_interval)
|
||||
)
|
||||
);
|
||||
if (! due) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
process.stderr.write(
|
||||
lib_plankton.string.coin(
|
||||
"-- {{check_name}}\n",
|
||||
{
|
||||
"check_name": check.name,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// execute check and set new state
|
||||
let result;
|
||||
try {
|
||||
result = await check_kind_implementations[check.kind].run(check.parameters);
|
||||
}
|
||||
catch (error) {
|
||||
result = {
|
||||
"condition": _heimdall.enum_condition.unknown,
|
||||
"info": {
|
||||
"cause": lib_plankton.translate.get("misc.check_procedure_failed"),
|
||||
"error": error.toString(),
|
||||
},
|
||||
}
|
||||
}
|
||||
const count : (null | int) = (
|
||||
(
|
||||
(old_item_state === null)
|
||||
||
|
||||
(old_item_state.condition !== result.condition)
|
||||
)
|
||||
? 1
|
||||
: (
|
||||
(
|
||||
(! (old_item_state.count === null))
|
||||
&&
|
||||
((old_item_state.count + 1) <= check.threshold)
|
||||
)
|
||||
? (old_item_state.count + 1)
|
||||
: null
|
||||
)
|
||||
)
|
||||
const shall_send_notification : boolean = (
|
||||
(
|
||||
(
|
||||
(! (count === null))
|
||||
&&
|
||||
(count == check.threshold)
|
||||
)
|
||||
||
|
||||
(
|
||||
(count === null)
|
||||
&&
|
||||
check.annoy
|
||||
)
|
||||
||
|
||||
(
|
||||
(count === null)
|
||||
&&
|
||||
(
|
||||
(! (old_item_state === null))
|
||||
&&
|
||||
(! (old_item_state.last_notification_timestamp === null))
|
||||
&&
|
||||
(! (check.schedule.reminding_interval === null))
|
||||
&&
|
||||
(
|
||||
(timestamp - old_item_state.last_notification_timestamp)
|
||||
>=
|
||||
check.schedule.reminding_interval
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
&&
|
||||
(
|
||||
(result.condition !== _heimdall.enum_condition.ok)
|
||||
||
|
||||
args["send_ok_notifications"]
|
||||
)
|
||||
)
|
||||
const new_item_state : _heimdall.type_item_state = {
|
||||
"timestamp": timestamp,
|
||||
"condition": result.condition,
|
||||
"count": count,
|
||||
"last_notification_timestamp": (
|
||||
shall_send_notification
|
||||
? timestamp
|
||||
: (
|
||||
(old_item_state === null)
|
||||
? null
|
||||
: old_item_state.last_notification_timestamp
|
||||
)
|
||||
),
|
||||
}
|
||||
await _heimdall.state_repository.feed(
|
||||
database_path,
|
||||
check.name,
|
||||
timestamp,
|
||||
result.condition,
|
||||
shall_send_notification,
|
||||
result.info
|
||||
);
|
||||
|
||||
// send notifications
|
||||
if (! shall_send_notification) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
check.notifications.forEach(
|
||||
notification => {
|
||||
notification_kind_implementations[notification.kind].notify(
|
||||
notification.parameters,
|
||||
check.name,
|
||||
check,
|
||||
new_item_state,
|
||||
Object.assign(
|
||||
(
|
||||
(check.custom === null)
|
||||
? {}
|
||||
: {"custom": check.custom}
|
||||
),
|
||||
result.info
|
||||
)
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// drop mutex file
|
||||
await (
|
||||
new Promise<void>(
|
||||
(resolve, reject) => {
|
||||
nm_fs.unlink(
|
||||
args["mutex_path"],
|
||||
() => {
|
||||
resolve(undefined);
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
365
source/logic/master.ts
Normal file
365
source/logic/master.ts
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
namespace _heimdall.master
|
||||
{
|
||||
|
||||
/**
|
||||
* @todo automated tests
|
||||
*/
|
||||
export function determine_due(
|
||||
check : _heimdall.type_check,
|
||||
timestamp : int,
|
||||
old_item_state : (null | _heimdall.type_item_state),
|
||||
) : boolean
|
||||
{
|
||||
return (
|
||||
(old_item_state === null)
|
||||
||
|
||||
(old_item_state.condition !== _heimdall.enum_condition.ok)
|
||||
||
|
||||
((timestamp - old_item_state.timestamp) >= check.schedule.regular_interval)
|
||||
||
|
||||
(
|
||||
(! (old_item_state.count === null))
|
||||
&&
|
||||
((timestamp - old_item_state.timestamp) >= check.schedule.attentive_interval)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo automated tests
|
||||
*/
|
||||
function determine_shall_send_notification(
|
||||
check : _heimdall.type_check,
|
||||
send_ok_notifications : boolean,
|
||||
count : (null | int),
|
||||
timestamp : int,
|
||||
old_item_state : (null | _heimdall.type_item_state),
|
||||
result : _heimdall.type_result
|
||||
) : boolean
|
||||
{
|
||||
return (
|
||||
(
|
||||
(
|
||||
(! (count === null))
|
||||
&&
|
||||
(count == check.threshold)
|
||||
)
|
||||
||
|
||||
(
|
||||
(count === null)
|
||||
&&
|
||||
check.annoy
|
||||
)
|
||||
||
|
||||
(
|
||||
(count === null)
|
||||
&&
|
||||
(
|
||||
(! (old_item_state === null))
|
||||
&&
|
||||
(! (old_item_state.last_notification_timestamp === null))
|
||||
&&
|
||||
(! (check.schedule.reminding_interval === null))
|
||||
&&
|
||||
(
|
||||
(timestamp - old_item_state.last_notification_timestamp)
|
||||
>=
|
||||
check.schedule.reminding_interval
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
&&
|
||||
(
|
||||
(result.condition !== _heimdall.enum_condition.ok)
|
||||
||
|
||||
send_ok_notifications
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function clean(
|
||||
options : {
|
||||
time_to_live ?: int;
|
||||
erase_state ?: boolean;
|
||||
} = {}
|
||||
) : Promise<void>
|
||||
{
|
||||
options = Object.assign(
|
||||
{
|
||||
"time_to_live": (7 * 24 * 60 * 60),
|
||||
"erase_state": false,
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
const count : int = await _heimdall.state_repository.clean(
|
||||
options.time_to_live,
|
||||
options.erase_state
|
||||
);
|
||||
lib_plankton.log.info(
|
||||
lib_plankton.translate.get(
|
||||
"cleanup_info",
|
||||
{
|
||||
"count": count.toFixed(0),
|
||||
}
|
||||
),
|
||||
{
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function wrap_database(
|
||||
database_path_raw : (null | string),
|
||||
order_path : string,
|
||||
procedure : (() => Promise<void>)
|
||||
) : Promise<void>
|
||||
{
|
||||
const nm_path = require("path");
|
||||
const database_path : string = (
|
||||
(database_path_raw !== null)
|
||||
? database_path_raw
|
||||
: nm_path.join(
|
||||
// TODO get path from fs or path module?
|
||||
"/tmp",
|
||||
lib_plankton.string.coin(
|
||||
"monitoring-state-{{id}}.sqlite",
|
||||
{
|
||||
"id": lib_plankton.call.convey(
|
||||
order_path,
|
||||
[
|
||||
nm_path.normalize,
|
||||
// encode(ascii),
|
||||
x => lib_plankton.sha256.get(x),
|
||||
x => x.slice(0, 8),
|
||||
]
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
lib_plankton.log.info(
|
||||
lib_plankton.translate.get("misc.state_file_path"),
|
||||
{
|
||||
"database_path": database_path,
|
||||
}
|
||||
);
|
||||
await _heimdall.state_repository.init(database_path);
|
||||
await procedure();
|
||||
await _heimdall.state_repository.kill();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo outsource?
|
||||
*/
|
||||
export async function wrap_mutex(
|
||||
mutex_path : string,
|
||||
procedure : (() => Promise<void>)
|
||||
) : Promise<void>
|
||||
{
|
||||
const nm_fs = require("fs");
|
||||
if (nm_fs.existsSync(mutex_path)) {
|
||||
lib_plankton.log.error(
|
||||
lib_plankton.translate.get("misc.still_running"),
|
||||
{
|
||||
"mutex_path": mutex_path,
|
||||
}
|
||||
);
|
||||
return Promise.reject();
|
||||
}
|
||||
else {
|
||||
await lib_plankton.file.write(mutex_path, "");
|
||||
await procedure();
|
||||
await lib_plankton.file.delete_(mutex_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* central processing procedure
|
||||
*/
|
||||
export async function run(
|
||||
order : _heimdall.type_order,
|
||||
options : {
|
||||
send_ok_notifications ?: boolean;
|
||||
} = {}
|
||||
) : Promise<void>
|
||||
{
|
||||
options = Object.assign(
|
||||
{
|
||||
"send_ok_notifications": false
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
const notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind> = _heimdall.notification_kinds.get_implementations();
|
||||
const check_kind_implementations : Record<string, _heimdall.check_kinds.type_check_kind> = _heimdall.check_kinds.get_implementations();
|
||||
for await (const check of order.checks) {
|
||||
if (! check.active) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
let old_item_state : (null | _heimdall.type_item_state);
|
||||
|
||||
const last_notification_timestamp : (null | int) = await _heimdall.state_repository.get_last_notification_timestamp(
|
||||
check.name
|
||||
);
|
||||
|
||||
const rows : Array<
|
||||
{
|
||||
timestamp : int;
|
||||
condition : _heimdall.enum_condition;
|
||||
notification_sent : boolean;
|
||||
}
|
||||
> = await _heimdall.state_repository.probe(
|
||||
check.name,
|
||||
(check.threshold + 1),
|
||||
);
|
||||
if (rows.length <= 0) {
|
||||
old_item_state = null;
|
||||
}
|
||||
else {
|
||||
let count : int = 1;
|
||||
rows.slice(1).some(
|
||||
(row) => {
|
||||
if (row.condition === rows[0].condition) {
|
||||
count += 1;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
if (count > check.threshold) {
|
||||
count = null;
|
||||
}
|
||||
else {
|
||||
// do nothing
|
||||
}
|
||||
old_item_state = {
|
||||
"timestamp": rows[0].timestamp,
|
||||
"condition": rows[0].condition,
|
||||
"count": count,
|
||||
"last_notification_timestamp": last_notification_timestamp,
|
||||
}
|
||||
|
||||
const timestamp : int = _heimdall.get_current_timestamp();
|
||||
const due : boolean = determine_due(
|
||||
check,
|
||||
timestamp,
|
||||
old_item_state
|
||||
);
|
||||
if (! due) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
process.stderr.write(
|
||||
lib_plankton.string.coin(
|
||||
"-- {{check_name}}\n",
|
||||
{
|
||||
"check_name": check.name,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// execute check and set new state
|
||||
let result : _heimdall.type_result;
|
||||
try {
|
||||
result = await check_kind_implementations[check.kind].run(check.parameters);
|
||||
}
|
||||
catch (error) {
|
||||
result = {
|
||||
"condition": _heimdall.enum_condition.unknown,
|
||||
"info": {
|
||||
"cause": lib_plankton.translate.get("misc.check_procedure_failed"),
|
||||
"error": error.toString(),
|
||||
},
|
||||
};
|
||||
}
|
||||
const count : (null | int) = (
|
||||
(
|
||||
(old_item_state === null)
|
||||
||
|
||||
(old_item_state.condition !== result.condition)
|
||||
)
|
||||
? 1
|
||||
: (
|
||||
(
|
||||
(! (old_item_state.count === null))
|
||||
&&
|
||||
((old_item_state.count + 1) <= check.threshold)
|
||||
)
|
||||
? (old_item_state.count + 1)
|
||||
: null
|
||||
)
|
||||
);
|
||||
const shall_send_notification : boolean = determine_shall_send_notification(
|
||||
check,
|
||||
options.send_ok_notifications,
|
||||
count,
|
||||
timestamp,
|
||||
old_item_state,
|
||||
result
|
||||
);
|
||||
const new_item_state : _heimdall.type_item_state = {
|
||||
"timestamp": timestamp,
|
||||
"condition": result.condition,
|
||||
"count": count,
|
||||
"last_notification_timestamp": (
|
||||
shall_send_notification
|
||||
? timestamp
|
||||
: (
|
||||
(old_item_state === null)
|
||||
? null
|
||||
: old_item_state.last_notification_timestamp
|
||||
)
|
||||
),
|
||||
}
|
||||
await _heimdall.state_repository.feed(
|
||||
check.name,
|
||||
timestamp,
|
||||
result.condition,
|
||||
shall_send_notification,
|
||||
result.info
|
||||
);
|
||||
|
||||
// send notifications
|
||||
if (! shall_send_notification) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
check.notifications.forEach(
|
||||
notification => {
|
||||
notification_kind_implementations[notification.kind].notify(
|
||||
notification.parameters,
|
||||
check.name,
|
||||
check,
|
||||
new_item_state,
|
||||
Object.assign(
|
||||
(
|
||||
(check.custom === null)
|
||||
? {}
|
||||
: {"custom": check.custom}
|
||||
),
|
||||
result.info
|
||||
)
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
namespace _heimdall.notification_kinds
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export type type_notification_kind = {
|
||||
parameters_schema : (() => _heimdall.helpers.json_schema.type_schema);
|
||||
normalize_order_node : ((node : any) => any);
|
||||
notify : (
|
||||
parameters : any,
|
||||
name : string,
|
||||
data : type_check,
|
||||
state : type_item_state,
|
||||
info : any
|
||||
) => Promise<void>;
|
||||
};
|
||||
|
||||
}
|
||||
65
source/logic/notification_kinds/_base.ts
Normal file
65
source/logic/notification_kinds/_base.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
namespace _heimdall.notification_kinds
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export type type_notification_kind = {
|
||||
parameters_schema : (
|
||||
()
|
||||
=>
|
||||
_heimdall.helpers.json_schema.type_schema
|
||||
);
|
||||
normalize_order_node : (
|
||||
(node : any)
|
||||
=>
|
||||
any
|
||||
);
|
||||
notify : (
|
||||
(
|
||||
parameters : any,
|
||||
name : string,
|
||||
data : type_check,
|
||||
state : type_item_state,
|
||||
info : any
|
||||
)
|
||||
=>
|
||||
Promise<void>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
var _implementations : Record<string, type_notification_kind> = {};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function register_implementation(
|
||||
name : string,
|
||||
notification_kind : type_notification_kind
|
||||
) : void
|
||||
{
|
||||
_implementations[name] = notification_kind;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function get_implementation(
|
||||
name : string
|
||||
) : type_notification_kind
|
||||
{
|
||||
return _implementations[name];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function get_implementations(
|
||||
) : Record<string, type_notification_kind>
|
||||
{
|
||||
return _implementations;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -57,14 +57,13 @@ namespace _heimdall.notification_kinds.console
|
|||
|
||||
/**
|
||||
*/
|
||||
export function notification_kind_implementation(
|
||||
) : type_notification_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"console",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"notify": notify,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,14 +128,13 @@ namespace _heimdall.notification_kinds.email
|
|||
|
||||
/**
|
||||
*/
|
||||
export function notification_kind_implementation(
|
||||
) : type_notification_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"email",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"notify": notify,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,14 +114,13 @@ namespace _heimdall.notification_kinds.libnotify
|
|||
|
||||
/**
|
||||
*/
|
||||
export function notification_kind_implementation(
|
||||
) : type_notification_kind
|
||||
{
|
||||
return {
|
||||
register_implementation(
|
||||
"libnotify",
|
||||
{
|
||||
"parameters_schema": parameters_schema,
|
||||
"normalize_order_node": normalize_order_node,
|
||||
"notify": notify,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,9 +107,9 @@ namespace _heimdall.order
|
|||
/**
|
||||
*/
|
||||
function schema_notifications(
|
||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>
|
||||
) : _heimdall.helpers.json_schema.type_schema
|
||||
{
|
||||
const notification_kind_implementations = _heimdall.notification_kinds.get_implementations();
|
||||
return {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
|
@ -149,10 +149,9 @@ namespace _heimdall.order
|
|||
/**
|
||||
*/
|
||||
export function schema_root(
|
||||
check_kind_implementations : Record<string, _heimdall.check_kinds.type_check_kind>,
|
||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
||||
) : _heimdall.helpers.json_schema.type_schema
|
||||
{
|
||||
const check_kind_implementations = _heimdall.check_kinds.get_implementations();
|
||||
return {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
|
@ -166,7 +165,7 @@ namespace _heimdall.order
|
|||
"threshold": schema_threshold(),
|
||||
"annoy": schema_annoy(),
|
||||
"schedule": schema_schedule(),
|
||||
"notifications": schema_notifications(notification_kind_implementations),
|
||||
"notifications": schema_notifications(),
|
||||
},
|
||||
"required": [
|
||||
],
|
||||
|
|
@ -198,7 +197,7 @@ namespace _heimdall.order
|
|||
"threshold": schema_threshold(),
|
||||
"annoy": schema_annoy(),
|
||||
"schedule": schema_schedule(),
|
||||
"notifications": schema_notifications(notification_kind_implementations),
|
||||
"notifications": schema_notifications(),
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
|
|
@ -301,10 +300,10 @@ namespace _heimdall.order
|
|||
/**
|
||||
*/
|
||||
function normalize_notification(
|
||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
||||
node : any
|
||||
) : type_notification
|
||||
{
|
||||
const notification_kind_implementations = _heimdall.notification_kinds.get_implementations();
|
||||
if (! (node["kind"] in notification_kind_implementations)) {
|
||||
throw new Error("invalid notification kind: " + node["kind"]);
|
||||
}
|
||||
|
|
@ -320,7 +319,6 @@ namespace _heimdall.order
|
|||
/**
|
||||
*/
|
||||
function normalize_defaults(
|
||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
||||
node : any
|
||||
) : type_check_common
|
||||
{
|
||||
|
|
@ -346,7 +344,7 @@ namespace _heimdall.order
|
|||
"schedule": node_["schedule"],
|
||||
"notifications": (
|
||||
node_["notifications"]
|
||||
.map(x => normalize_notification(notification_kind_implementations, x))
|
||||
.map(x => normalize_notification(x))
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
@ -355,8 +353,6 @@ namespace _heimdall.order
|
|||
/**
|
||||
*/
|
||||
function normalize_check(
|
||||
check_kind_implementations : Record<string, _heimdall.check_kinds.type_check_kind>,
|
||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
||||
defaults : type_check_common,
|
||||
node : {
|
||||
name : string;
|
||||
|
|
@ -364,6 +360,8 @@ namespace _heimdall.order
|
|||
}
|
||||
) : type_check
|
||||
{
|
||||
const check_kind_implementations = _heimdall.check_kinds.get_implementations();
|
||||
const notification_kind_implementations = _heimdall.notification_kinds.get_implementations();
|
||||
if (! ("name" in node)) {
|
||||
throw new Error("missing mandatory field in 'check' node: 'name'");
|
||||
}
|
||||
|
|
@ -410,7 +408,7 @@ namespace _heimdall.order
|
|||
check.notifications = (
|
||||
node_["notifications"]
|
||||
.map(
|
||||
x => normalize_notification(notification_kind_implementations, x),
|
||||
x => normalize_notification(x),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -427,8 +425,6 @@ namespace _heimdall.order
|
|||
/**
|
||||
*/
|
||||
function normalize_root(
|
||||
check_kind_implementations : Record<string, _heimdall.check_kinds.type_check_kind>,
|
||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
||||
node : any,
|
||||
options : {
|
||||
use_implicit_default_values ?: boolean;
|
||||
|
|
@ -440,7 +436,8 @@ namespace _heimdall.order
|
|||
"use_implicit_default_values": true,
|
||||
},
|
||||
options
|
||||
)
|
||||
);
|
||||
|
||||
let counts : Record<string, int> = {};
|
||||
const checks_raw : Array<any> = (
|
||||
("checks" in node)
|
||||
|
|
@ -480,7 +477,6 @@ namespace _heimdall.order
|
|||
const defaults : type_check_common = (
|
||||
options.use_implicit_default_values
|
||||
? normalize_defaults(
|
||||
notification_kind_implementations,
|
||||
defaults_raw
|
||||
)
|
||||
: defaults_raw
|
||||
|
|
@ -497,8 +493,6 @@ namespace _heimdall.order
|
|||
checks_raw
|
||||
.map(
|
||||
node_ => normalize_check(
|
||||
check_kind_implementations,
|
||||
notification_kind_implementations,
|
||||
defaults,
|
||||
node_
|
||||
)
|
||||
|
|
@ -512,8 +506,6 @@ namespace _heimdall.order
|
|||
/**
|
||||
*/
|
||||
export async function load(
|
||||
check_kind_implementations : Record<string, _heimdall.check_kinds.type_check_kind>,
|
||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
||||
path : string,
|
||||
options : {
|
||||
root ?: boolean;
|
||||
|
|
@ -529,7 +521,8 @@ namespace _heimdall.order
|
|||
"already_included": [],
|
||||
},
|
||||
options
|
||||
)
|
||||
);
|
||||
|
||||
if (options.already_included.includes(path)) {
|
||||
throw new Error("circular dependency detected")
|
||||
}
|
||||
|
|
@ -546,8 +539,6 @@ namespace _heimdall.order
|
|||
for (let index = 0; index < includes.length; index += 1) {
|
||||
const path_ : string = includes[index];
|
||||
const sub_order : type_order = await load(
|
||||
check_kind_implementations,
|
||||
notification_kind_implementations,
|
||||
(
|
||||
nm_path.isAbsolute(path_)
|
||||
? path_
|
||||
|
|
@ -582,8 +573,6 @@ namespace _heimdall.order
|
|||
order_raw.includes = [];
|
||||
}
|
||||
return normalize_root(
|
||||
check_kind_implementations,
|
||||
notification_kind_implementations,
|
||||
order_raw,
|
||||
{
|
||||
"use_implicit_default_values": options["root"],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
namespace _heimdall.state_repository
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
var _connection : (null | lib_plankton.sqlite.type_connection) = null;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
function condition_decode(
|
||||
|
|
@ -33,12 +38,32 @@ namespace _heimdall.state_repository
|
|||
|
||||
/**
|
||||
*/
|
||||
export async function setup(
|
||||
export async function init(
|
||||
database_path : string
|
||||
) : Promise<void>
|
||||
{
|
||||
const result = await _heimdall.helpers.sqlite.query_set(
|
||||
database_path,
|
||||
_connection = await lib_plankton.sqlite.get_connection(database_path);
|
||||
await setup();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function kill(
|
||||
) : Promise<void>
|
||||
{
|
||||
await lib_plankton.sqlite.drop_connection(_connection);
|
||||
_connection = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function setup(
|
||||
) : Promise<void>
|
||||
{
|
||||
const result = await lib_plankton.sqlite.query_set(
|
||||
_connection,
|
||||
{
|
||||
"template": "CREATE TABLE IF NOT EXISTS results(check_name TEXT NOT NULL, timestamp INTEGER NOT NULL, condition TEXT NOT NULL, notification_sent BOOLEAN NOT NULL, info TEXT NOT NULL);",
|
||||
"arguments": {
|
||||
|
|
@ -51,13 +76,12 @@ namespace _heimdall.state_repository
|
|||
/**
|
||||
*/
|
||||
export async function clean(
|
||||
database_path : string,
|
||||
time_to_live : int,
|
||||
erase_state : boolean
|
||||
) : Promise<int>
|
||||
{
|
||||
const result = await _heimdall.helpers.sqlite.query_put(
|
||||
database_path,
|
||||
const result = await lib_plankton.sqlite.query_put(
|
||||
_connection,
|
||||
{
|
||||
"template": "DELETE FROM results WHERE ((timestamp < :timestamp_min) OR :erase_state);",
|
||||
"arguments": {
|
||||
|
|
@ -73,7 +97,6 @@ namespace _heimdall.state_repository
|
|||
/**
|
||||
*/
|
||||
export async function probe(
|
||||
database_path : string,
|
||||
check_name : string,
|
||||
threshold : int
|
||||
) : Promise<
|
||||
|
|
@ -86,8 +109,8 @@ namespace _heimdall.state_repository
|
|||
>
|
||||
>
|
||||
{
|
||||
const rows : Array<Array<any>> = await _heimdall.helpers.sqlite.query_get(
|
||||
database_path,
|
||||
const rows : Array<Record<string, any>> = await lib_plankton.sqlite.query_get(
|
||||
_connection,
|
||||
{
|
||||
"template": "SELECT timestamp, condition, notification_sent FROM results WHERE (check_name = :check_name) ORDER BY timestamp DESC LIMIT :limit;",
|
||||
"arguments": {
|
||||
|
|
@ -100,9 +123,9 @@ namespace _heimdall.state_repository
|
|||
rows
|
||||
.map(
|
||||
row => ({
|
||||
"timestamp": row[0],
|
||||
"condition": condition_decode(row[1]),
|
||||
"notification_sent": row[2],
|
||||
"timestamp": row["timestamp"],
|
||||
"condition": condition_decode(row["condition"]),
|
||||
"notification_sent": row["notification_sent"],
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
@ -112,27 +135,25 @@ namespace _heimdall.state_repository
|
|||
/**
|
||||
*/
|
||||
export async function get_last_notification_timestamp(
|
||||
database_path : string,
|
||||
check_name : string
|
||||
) : Promise<(null | int)>
|
||||
{
|
||||
const rows : Array<Array<any>> = await _heimdall.helpers.sqlite.query_get(
|
||||
database_path,
|
||||
const rows : Array<Record<string, any>> = await lib_plankton.sqlite.query_get(
|
||||
_connection,
|
||||
{
|
||||
"template": "SELECT MAX(timestamp) FROM results WHERE (check_name = :check_name) AND (notification_sent = TRUE);",
|
||||
"template": "SELECT MAX(timestamp) AS max_timestamp FROM results WHERE (check_name = :check_name) AND (notification_sent = TRUE);",
|
||||
"arguments": {
|
||||
"check_name": check_name,
|
||||
},
|
||||
}
|
||||
);
|
||||
return rows[0][0];
|
||||
return rows[0]["max_timestamp"];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function feed(
|
||||
database_path : string,
|
||||
check_name : string,
|
||||
timestamp : int,
|
||||
condition : _heimdall.enum_condition,
|
||||
|
|
@ -140,8 +161,8 @@ namespace _heimdall.state_repository
|
|||
info : any
|
||||
) : Promise<void>
|
||||
{
|
||||
await _heimdall.helpers.sqlite.query_put(
|
||||
database_path,
|
||||
await lib_plankton.sqlite.query_put(
|
||||
_connection,
|
||||
{
|
||||
"template": "INSERT INTO results(check_name, timestamp, condition, notification_sent, info) VALUES (:check_name, :timestamp, :condition, :notification_sent, :info);",
|
||||
"arguments": {
|
||||
|
|
|
|||
102
source/test/test.mocha.ts
Normal file
102
source/test/test.mocha.ts
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
const nm_assert = require("assert");
|
||||
|
||||
declare var describe;
|
||||
declare var it;
|
||||
|
||||
_heimdall.init();
|
||||
describe(
|
||||
"heimdall",
|
||||
() => {
|
||||
function datetimestring_to_timestamp(datetimestring) {
|
||||
return Math.floor((new Date(datetimestring)).getTime() / 1000);
|
||||
};
|
||||
describe(
|
||||
"master.determine_due",
|
||||
() => {
|
||||
const cases = [
|
||||
{
|
||||
"name": "regular interval hit",
|
||||
"input": {
|
||||
"check": {
|
||||
"active": true,
|
||||
"threshold": 1,
|
||||
"annoy": false,
|
||||
"schedule": {
|
||||
"regular_interval": 3600,
|
||||
"attentive_interval": 120,
|
||||
"reminding_interval": 86400,
|
||||
},
|
||||
"notifications": [],
|
||||
"name": "test",
|
||||
"title": "Test",
|
||||
"kind": "BOGUS",
|
||||
"parameters": {},
|
||||
"custom": null,
|
||||
},
|
||||
"timestamp": "2023-01-15T12:30:00",
|
||||
"old_item_state": {
|
||||
"timestamp": "2023-01-15T11:00:00",
|
||||
"condition": _heimdall.enum_condition.ok,
|
||||
"count": 0,
|
||||
"last_notification_timestamp": "2023-01-15T10:00:00"
|
||||
}
|
||||
},
|
||||
"output": true,
|
||||
},
|
||||
{
|
||||
"name": "regular interval not hit",
|
||||
"input": {
|
||||
"check": {
|
||||
"active": true,
|
||||
"threshold": 1,
|
||||
"annoy": false,
|
||||
"schedule": {
|
||||
"regular_interval": 3600,
|
||||
"attentive_interval": 120,
|
||||
"reminding_interval": 86400,
|
||||
},
|
||||
"notifications": [],
|
||||
"name": "test",
|
||||
"title": "Test",
|
||||
"kind": "BOGUS",
|
||||
"parameters": {},
|
||||
"custom": null,
|
||||
},
|
||||
"timestamp": "2023-01-15T11:30:00",
|
||||
"old_item_state": {
|
||||
"timestamp": "2023-01-15T11:00:00",
|
||||
"condition": _heimdall.enum_condition.ok,
|
||||
"count": 0,
|
||||
"last_notification_timestamp": "2023-01-15T10:00:00"
|
||||
}
|
||||
},
|
||||
"output": false,
|
||||
},
|
||||
];
|
||||
cases.forEach(
|
||||
case_ => {
|
||||
it(
|
||||
case_.name,
|
||||
() => {
|
||||
// execution
|
||||
const result : boolean = _heimdall.master.determine_due(
|
||||
case_.input["check"],
|
||||
datetimestring_to_timestamp(case_.input["timestamp"]),
|
||||
{
|
||||
"timestamp": datetimestring_to_timestamp(case_.input["old_item_state"]["timestamp"]),
|
||||
"condition": case_.input["old_item_state"]["condition"],
|
||||
"count": case_.input["old_item_state"]["count"],
|
||||
"last_notification_timestamp": datetimestring_to_timestamp(case_.input["old_item_state"]["last_notification_timestamp"]),
|
||||
}
|
||||
);
|
||||
|
||||
// assertions
|
||||
nm_assert.equal(result, case_.output);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
definitions = [
|
||||
{
|
||||
"name": "lib.string_coin",
|
||||
"procedure": lambda input_: string_coin(input_["template"], input_["arguments"]),
|
||||
"cases": [
|
||||
{
|
||||
"input": {
|
||||
"template": "{{sachen}} sind {{farbe}}",
|
||||
"arguments": {
|
||||
"farbe": "rot",
|
||||
},
|
||||
},
|
||||
"output": "{{sachen}} sind rot"
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"template": "{{sachen}} sind {{farbe}}",
|
||||
"arguments": {
|
||||
},
|
||||
},
|
||||
"output": "{{sachen}} sind {{farbe}}"
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"template": "{{sachen}} sind {{farbe}}",
|
||||
"arguments": {
|
||||
"sachen": "rosen",
|
||||
"farbe": "rot",
|
||||
},
|
||||
},
|
||||
"output": "rosen sind rot"
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"template": "{{sachen}} sind {{farbe}}",
|
||||
"arguments": {
|
||||
"sachen": "rosen",
|
||||
"farbe": "rot",
|
||||
"ort": "frankreich",
|
||||
},
|
||||
},
|
||||
"output": "rosen sind rot"
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "lib.format_bytes",
|
||||
"procedure": lambda input_: format_bytes(input_),
|
||||
"cases": [
|
||||
{
|
||||
"input": 999,
|
||||
"output": "999 B",
|
||||
},
|
||||
{
|
||||
"input": 1000,
|
||||
"output": "1.0 KB",
|
||||
},
|
||||
{
|
||||
"input": 1000000,
|
||||
"output": "1.0 MB",
|
||||
},
|
||||
{
|
||||
"input": 1000000000,
|
||||
"output": "1.0 GB",
|
||||
},
|
||||
{
|
||||
"input": 1000000000000,
|
||||
"output": "1.0 TB",
|
||||
},
|
||||
{
|
||||
"input": 1000000000000000,
|
||||
"output": "1.0 PB",
|
||||
},
|
||||
{
|
||||
"input": 1000000000000000000,
|
||||
"output": "1000.0 PB",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
for definition in definitions:
|
||||
fails = 0
|
||||
for index in range(len(definition["cases"])):
|
||||
case = definition["cases"][index]
|
||||
output_actual = definition["procedure"](case["input"])
|
||||
output_expected = case["output"]
|
||||
passed = (output_actual == output_expected)
|
||||
fails += (0 if passed else 1)
|
||||
info = {
|
||||
"input": case["input"],
|
||||
"output_expected": output_expected,
|
||||
"output_actual": output_actual,
|
||||
}
|
||||
_sys.stderr.write(
|
||||
"[%s] %s.%u%s\n"
|
||||
% (
|
||||
("+" if passed else "x"),
|
||||
definition["name"],
|
||||
index,
|
||||
("" if passed else (": " + _json.dumps(info))),
|
||||
)
|
||||
)
|
||||
_sys.exit(1 if (fails > 0) else 0)
|
||||
1
todo.md
1
todo.md
|
|
@ -1,4 +1,3 @@
|
|||
- neu schreiben in TypeScript (und plankton dafür nutzen?)
|
||||
- Benachrichtigungen versenden, wenn ein Zustand sich wieder normalisiert hat (aber vorher über dem Schwellwert oft nicht OK war)
|
||||
- Selbst-Test
|
||||
- Benachrichtigungs-Kanäle:
|
||||
|
|
|
|||
21
tools/build
21
tools/build
|
|
@ -2,13 +2,24 @@
|
|||
|
||||
## vars
|
||||
|
||||
path_prj_from=tools/heimdall.prj.json
|
||||
path_prj_to=heimdall.prj.json
|
||||
path_prj_core_from=tools/heimdall-core.prj.json
|
||||
path_prj_core_to=heimdall-core.prj.json
|
||||
path_prj_app_from=tools/heimdall-app.prj.json
|
||||
path_prj_app_to=heimdall-app.prj.json
|
||||
path_prj_test_from=tools/heimdall-test.prj.json
|
||||
path_prj_test_to=heimdall-test.prj.json
|
||||
|
||||
|
||||
## exec
|
||||
|
||||
cp ${path_prj_from} ${path_prj_to}
|
||||
koralle --execute ${path_prj_to}
|
||||
cp ${path_prj_core_from} ${path_prj_core_to}
|
||||
cp ${path_prj_app_from} ${path_prj_app_to}
|
||||
cp ${path_prj_test_from} ${path_prj_test_to}
|
||||
|
||||
koralle --execute ${path_prj_app_to}
|
||||
chmod +r build/heimdall
|
||||
rm ${path_prj_to}
|
||||
koralle --execute ${path_prj_test_to}
|
||||
|
||||
rm ${path_prj_test_to}
|
||||
rm ${path_prj_app_to}
|
||||
rm ${path_prj_core_to}
|
||||
|
|
|
|||
57
tools/heimdall-app.prj.json
Normal file
57
tools/heimdall-app.prj.json
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"name": "heimdall-app",
|
||||
"dependencies": [
|
||||
"heimdall-core.prj.json"
|
||||
],
|
||||
"roottask": {
|
||||
"name": "all",
|
||||
"type": "group",
|
||||
"sub": [
|
||||
{
|
||||
"name": "postprocess",
|
||||
"sub": [
|
||||
{
|
||||
"name": "link",
|
||||
"sub": [
|
||||
{
|
||||
"name": "compile",
|
||||
"type": "typescript",
|
||||
"parameters": {
|
||||
"inputs": [
|
||||
"lib/plankton/plankton.d.ts",
|
||||
"temp/heimdall-core.d.ts",
|
||||
"source/app/cli.ts"
|
||||
],
|
||||
"target": "es2020",
|
||||
"strict": true,
|
||||
"output": "temp/heimdall-app.raw.js"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "concat",
|
||||
"parameters": {
|
||||
"inputs": [
|
||||
"source/misc/head.js",
|
||||
"lib/plankton/plankton.js",
|
||||
"temp/heimdall-core.js",
|
||||
"temp/heimdall-app.raw.js"
|
||||
],
|
||||
"output": "temp/heimdall-app.js"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "script",
|
||||
"parameters": {
|
||||
"path": "tools/postprocess",
|
||||
"interpreter": null,
|
||||
"inputs": [
|
||||
"temp/heimdall-app.js"
|
||||
],
|
||||
"outputs": [
|
||||
"build/heimdall"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
59
tools/heimdall-core.prj.json
Normal file
59
tools/heimdall-core.prj.json
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"name": "heimdall-core",
|
||||
"dependencies": [
|
||||
],
|
||||
"roottask": {
|
||||
"name": "all",
|
||||
"type": "group",
|
||||
"sub": [
|
||||
{
|
||||
"name": "compile",
|
||||
"type": "typescript",
|
||||
"parameters": {
|
||||
"inputs": [
|
||||
"lib/plankton/plankton.d.ts",
|
||||
"source/base.ts",
|
||||
"source/helpers/json_schema.ts",
|
||||
"source/helpers/misc.ts",
|
||||
"source/logic/state_repository.ts",
|
||||
"source/logic/notification_kinds/_base.ts",
|
||||
"source/logic/notification_kinds/console.ts",
|
||||
"source/logic/notification_kinds/email.ts",
|
||||
"source/logic/notification_kinds/libnotify.ts",
|
||||
"source/logic/check_kinds/_base.ts",
|
||||
"source/logic/check_kinds/script.ts",
|
||||
"source/logic/check_kinds/http_request.ts",
|
||||
"source/logic/check_kinds/file_state.ts",
|
||||
"source/logic/check_kinds/tls_certificate.ts",
|
||||
"source/logic/check_kinds/generic_remote.ts",
|
||||
"source/logic/order.ts",
|
||||
"source/logic/master.ts",
|
||||
"source/init.ts"
|
||||
],
|
||||
"target": "es2020",
|
||||
"strict": true,
|
||||
"output": "temp/heimdall-core.js",
|
||||
"declaration": "temp/heimdall-core.d.ts"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "node_modules",
|
||||
"type": "copy",
|
||||
"parameters": {
|
||||
"folder": true,
|
||||
"input": "lib/node/node_modules/",
|
||||
"output": "build/node_modules/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "localization",
|
||||
"type": "copy",
|
||||
"parameters": {
|
||||
"folder": true,
|
||||
"input": "source/localization/",
|
||||
"output": "build/localization/"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
34
tools/heimdall-test.prj.json
Normal file
34
tools/heimdall-test.prj.json
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "heimdall-test",
|
||||
"dependencies": [
|
||||
"heimdall-core.prj.json"
|
||||
],
|
||||
"roottask": {
|
||||
"name": "link",
|
||||
"sub": [
|
||||
{
|
||||
"name": "compile",
|
||||
"type": "typescript",
|
||||
"parameters": {
|
||||
"inputs": [
|
||||
"lib/plankton/plankton.d.ts",
|
||||
"temp/heimdall-core.d.ts",
|
||||
"source/test/test.mocha.ts"
|
||||
],
|
||||
"target": "es2020",
|
||||
"strict": true,
|
||||
"output": "temp/heimdall-test.mocha.raw.js"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "concat",
|
||||
"parameters": {
|
||||
"inputs": [
|
||||
"lib/plankton/plankton.js",
|
||||
"temp/heimdall-core.js",
|
||||
"temp/heimdall-test.mocha.raw.js"
|
||||
],
|
||||
"output": "build/heimdall-test.mocha.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
{
|
||||
"name": "heimdall",
|
||||
"version": "0.8",
|
||||
"dependencies": [
|
||||
],
|
||||
"roottask": {
|
||||
"name": "logic",
|
||||
"type": "group",
|
||||
"sub": [
|
||||
{
|
||||
"name": "postprocess",
|
||||
"sub": [
|
||||
{
|
||||
"name": "link",
|
||||
"sub": [
|
||||
{
|
||||
"name": "compile",
|
||||
"type": "typescript",
|
||||
"parameters": {
|
||||
"inputs": [
|
||||
"lib/plankton/plankton.d.ts",
|
||||
"source/logic/base.ts",
|
||||
"source/logic/helpers/json_schema.ts",
|
||||
"source/logic/helpers/sqlite.ts",
|
||||
"source/logic/helpers/misc.ts",
|
||||
"source/logic/notification_kinds/_abstract.ts",
|
||||
"source/logic/notification_kinds/console.ts",
|
||||
"source/logic/notification_kinds/email.ts",
|
||||
"source/logic/notification_kinds/libnotify.ts",
|
||||
"source/logic/check_kinds/_abstract.ts",
|
||||
"source/logic/check_kinds/script.ts",
|
||||
"source/logic/check_kinds/http_request.ts",
|
||||
"source/logic/check_kinds/file_state.ts",
|
||||
"source/logic/check_kinds/tls_certificate.ts",
|
||||
"source/logic/check_kinds/generic_remote.ts",
|
||||
"source/logic/state_repository.ts",
|
||||
"source/logic/order.ts",
|
||||
"source/logic/main.ts"
|
||||
],
|
||||
"target": "es2020",
|
||||
"strict": true,
|
||||
"output": "temp/heimdall-unlinked"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "concat",
|
||||
"parameters": {
|
||||
"inputs": [
|
||||
"source/misc/head.js",
|
||||
"lib/plankton/plankton.js",
|
||||
"temp/heimdall-unlinked"
|
||||
],
|
||||
"output": "temp/heimdall-raw"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "script",
|
||||
"parameters": {
|
||||
"path": "tools/postprocess",
|
||||
"interpreter": null,
|
||||
"inputs": [
|
||||
"temp/heimdall-raw"
|
||||
],
|
||||
"outputs": [
|
||||
"build/heimdall"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"name": "node_modules",
|
||||
"type": "copy",
|
||||
"parameters": {
|
||||
"folder": true,
|
||||
"input": "lib/node/node_modules/",
|
||||
"output": "build/node_modules/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "localization",
|
||||
"type": "copy",
|
||||
"parameters": {
|
||||
"folder": true,
|
||||
"input": "source/localization/",
|
||||
"output": "build/localization/"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ modules="${modules} file"
|
|||
modules="${modules} translate"
|
||||
modules="${modules} args"
|
||||
modules="${modules} http"
|
||||
modules="${modules} sqlite"
|
||||
|
||||
|
||||
## exec
|
||||
|
|
|
|||
Loading…
Reference in a new issue