[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
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
function write_buffer(path: string, content: Buffer, options?: {}): Promise<void>;
|
function write_buffer(path: string, content: Buffer, options?: {}): Promise<void>;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function delete_(path: string): Promise<void>;
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.translate {
|
declare namespace lib_plankton.translate {
|
||||||
/**
|
/**
|
||||||
|
|
@ -1905,3 +1908,45 @@ declare namespace lib_plankton.http {
|
||||||
decode(x: string): type_response;
|
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) {
|
return (new Promise(function (resolve, reject) {
|
||||||
nm_fs.readFile(path, {
|
nm_fs.readFile(path, {
|
||||||
"encoding": "utf8",
|
"encoding": "utf8",
|
||||||
"flag": "r",
|
"flag": "r"
|
||||||
}, function (error, content) {
|
}, function (error, content) {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
resolve(content);
|
resolve(content);
|
||||||
|
|
@ -4293,7 +4293,7 @@ var lib_plankton;
|
||||||
var nm_fs = require("fs");
|
var nm_fs = require("fs");
|
||||||
return (new Promise(function (resolve, reject) {
|
return (new Promise(function (resolve, reject) {
|
||||||
nm_fs.readFile(path, {
|
nm_fs.readFile(path, {
|
||||||
"flag": "r",
|
"flag": "r"
|
||||||
}, function (error, content) {
|
}, function (error, content) {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
resolve(content);
|
resolve(content);
|
||||||
|
|
@ -4330,13 +4330,13 @@ var lib_plankton;
|
||||||
function write(path, content, options) {
|
function write(path, content, options) {
|
||||||
if (options === void 0) { options = {}; }
|
if (options === void 0) { options = {}; }
|
||||||
options = Object.assign({
|
options = Object.assign({
|
||||||
"encoding": "utf-8",
|
"encoding": "utf-8"
|
||||||
}, options);
|
}, options);
|
||||||
var nm_fs = require("fs");
|
var nm_fs = require("fs");
|
||||||
return (new Promise(function (resolve, reject) {
|
return (new Promise(function (resolve, reject) {
|
||||||
nm_fs.writeFile(path, content, {
|
nm_fs.writeFile(path, content, {
|
||||||
"encoding": options.encoding,
|
"encoding": options.encoding,
|
||||||
"flag": "w",
|
"flag": "w"
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
resolve(undefined);
|
resolve(undefined);
|
||||||
|
|
@ -4357,7 +4357,7 @@ var lib_plankton;
|
||||||
var nm_fs = require("fs");
|
var nm_fs = require("fs");
|
||||||
return (new Promise(function (resolve, reject) {
|
return (new Promise(function (resolve, reject) {
|
||||||
nm_fs.writeFile(path, content, {
|
nm_fs.writeFile(path, content, {
|
||||||
"flag": "w",
|
"flag": "w"
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
resolve(undefined);
|
resolve(undefined);
|
||||||
|
|
@ -4369,6 +4369,17 @@ var lib_plankton;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
file.write_buffer = write_buffer;
|
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 = {}));
|
})(file = lib_plankton.file || (lib_plankton.file = {}));
|
||||||
})(lib_plankton || (lib_plankton = {}));
|
})(lib_plankton || (lib_plankton = {}));
|
||||||
/*
|
/*
|
||||||
|
|
@ -4851,8 +4862,8 @@ var lib_plankton;
|
||||||
"info": info,
|
"info": info,
|
||||||
"hidden": hidden,
|
"hidden": hidden,
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"index": index,
|
"index": index
|
||||||
},
|
}
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
|
@ -4870,8 +4881,8 @@ var lib_plankton;
|
||||||
"hidden": hidden,
|
"hidden": hidden,
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"indicators_short": indicators_short,
|
"indicators_short": indicators_short,
|
||||||
"indicators_long": indicators_long,
|
"indicators_long": indicators_long
|
||||||
},
|
}
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
|
@ -5117,17 +5128,17 @@ var lib_plankton;
|
||||||
"symbols": {
|
"symbols": {
|
||||||
"delimiter": " ",
|
"delimiter": " ",
|
||||||
"prefix": "--",
|
"prefix": "--",
|
||||||
"assignment": "=",
|
"assignment": "="
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
"url": {
|
"url": {
|
||||||
"symbols": {
|
"symbols": {
|
||||||
"delimiter": "&",
|
"delimiter": "&",
|
||||||
"prefix": "",
|
"prefix": "",
|
||||||
"assignment": "=",
|
"assignment": "="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
|
|
@ -5204,14 +5215,14 @@ var lib_plankton;
|
||||||
"pattern_from": pattern_from,
|
"pattern_from": pattern_from,
|
||||||
"pattern_to": pattern_to,
|
"pattern_to": pattern_to,
|
||||||
"input": input,
|
"input": input,
|
||||||
"result": result,
|
"result": result
|
||||||
});
|
});
|
||||||
input = result;
|
input = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lib_plankton.log.debug("lib_args:read:current_input", {
|
lib_plankton.log.debug("lib_args:read:current_input", {
|
||||||
"input": input,
|
"input": input
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// parsing
|
// parsing
|
||||||
|
|
@ -5222,18 +5233,18 @@ var lib_plankton;
|
||||||
var index_expected_1 = 0;
|
var index_expected_1 = 0;
|
||||||
parts.forEach(function (part) {
|
parts.forEach(function (part) {
|
||||||
lib_plankton.log.debug("lib_args:read:analyzing", {
|
lib_plankton.log.debug("lib_args:read:analyzing", {
|
||||||
"part": part,
|
"part": part
|
||||||
});
|
});
|
||||||
var found = [
|
var found = [
|
||||||
function () {
|
function () {
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile", {
|
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++) {
|
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];
|
var _b = _a[_i], name = _b[0], argument = _b[1];
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", {
|
lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", {
|
||||||
"part": part,
|
"part": part,
|
||||||
"argument": argument.toString(),
|
"argument": argument.toString()
|
||||||
});
|
});
|
||||||
var pattern = "";
|
var pattern = "";
|
||||||
{
|
{
|
||||||
|
|
@ -5252,12 +5263,12 @@ var lib_plankton;
|
||||||
pattern += pattern_back;
|
pattern += pattern_back;
|
||||||
}
|
}
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", {
|
lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", {
|
||||||
"pattern": pattern,
|
"pattern": pattern
|
||||||
});
|
});
|
||||||
var regexp = new RegExp(pattern);
|
var regexp = new RegExp(pattern);
|
||||||
var matching = regexp.exec(part);
|
var matching = regexp.exec(part);
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", {
|
lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", {
|
||||||
"matching": matching,
|
"matching": matching
|
||||||
});
|
});
|
||||||
if (matching == null) {
|
if (matching == null) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|
@ -5271,7 +5282,7 @@ var lib_plankton;
|
||||||
},
|
},
|
||||||
function () {
|
function () {
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_positional", {
|
lib_plankton.log.debug("lib_args:read:probing_as_positional", {
|
||||||
"part": part,
|
"part": part
|
||||||
});
|
});
|
||||||
var positional = _this.filter(args.enum_kind.positional);
|
var positional = _this.filter(args.enum_kind.positional);
|
||||||
for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) {
|
for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) {
|
||||||
|
|
@ -5282,7 +5293,7 @@ var lib_plankton;
|
||||||
else {
|
else {
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", {
|
lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", {
|
||||||
"part": part,
|
"part": part,
|
||||||
"argument": argument.toString(),
|
"argument": argument.toString()
|
||||||
});
|
});
|
||||||
var pattern = "";
|
var pattern = "";
|
||||||
{
|
{
|
||||||
|
|
@ -5291,12 +5302,12 @@ var lib_plankton;
|
||||||
pattern += pattern_back;
|
pattern += pattern_back;
|
||||||
}
|
}
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", {
|
lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", {
|
||||||
"pattern": pattern,
|
"pattern": pattern
|
||||||
});
|
});
|
||||||
var regexp = new RegExp(pattern);
|
var regexp = new RegExp(pattern);
|
||||||
var matching = regexp.exec(part);
|
var matching = regexp.exec(part);
|
||||||
lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", {
|
lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", {
|
||||||
"matching": matching,
|
"matching": matching
|
||||||
});
|
});
|
||||||
if (matching == null) {
|
if (matching == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -5313,7 +5324,7 @@ var lib_plankton;
|
||||||
].some(function (x) { return x(); });
|
].some(function (x) { return x(); });
|
||||||
if (!found) {
|
if (!found) {
|
||||||
lib_plankton.log.warning("lib_args:read:could_not_parse", {
|
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 === null)
|
||||||
? ""
|
? ""
|
||||||
: request.query));
|
: request.query));
|
||||||
// console.info({target,options});
|
console.info({ target });
|
||||||
switch (options.implementation) {
|
switch (options.implementation) {
|
||||||
default: {
|
default: {
|
||||||
return Promise.reject("invalid implementation: " + options.implementation);
|
return Promise.reject("invalid implementation: " + options.implementation);
|
||||||
|
|
@ -6019,3 +6030,145 @@ var lib_plankton;
|
||||||
http.class_http_response = class_http_response;
|
http.class_http_response = class_http_response;
|
||||||
})(http = lib_plankton.http || (lib_plankton.http = {}));
|
})(http = lib_plankton.http || (lib_plankton.http = {}));
|
||||||
})(lib_plankton || (lib_plankton = {}));
|
})(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
|
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(
|
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.check_procedure_failed": "Prüfungs-Prozedur fehlgeschlagen",
|
||||||
"misc.still_running": "läuft bereits/noch",
|
"misc.still_running": "läuft bereits/noch",
|
||||||
"misc.cleanup_info": "{{count}} alte Ergebnis-Datensätze gelöscht",
|
"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.check_procedure_failed": "check procedure failed",
|
||||||
"misc.still_running": "already/still running",
|
"misc.still_running": "already/still running",
|
||||||
"misc.cleanup_info": "removed {{count}} old result entries",
|
"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(
|
register_implementation(
|
||||||
) : type_check_kind
|
"file_state",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"run": run,
|
"run": run,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -242,14 +242,13 @@ namespace _heimdall.check_kinds.generic_remote
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function check_kind_implementation(
|
register_implementation(
|
||||||
) : type_check_kind
|
"generic_remote",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"run": run,
|
"run": run,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -380,14 +380,13 @@ namespace _heimdall.check_kinds.http_request
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function check_kind_implementation(
|
register_implementation(
|
||||||
) : type_check_kind
|
"http_request",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"run": run,
|
"run": run,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,14 +118,13 @@ namespace _heimdall.check_kinds.script
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function check_kind_implementation(
|
register_implementation(
|
||||||
) : type_check_kind
|
"script",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"run": run,
|
"run": run,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,14 +237,13 @@ namespace _heimdall.check_kinds.tls_certificate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function check_kind_implementation(
|
register_implementation(
|
||||||
) : type_check_kind
|
"tls_certificate",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"run": run,
|
"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(
|
register_implementation(
|
||||||
) : type_notification_kind
|
"console",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"notify": notify,
|
"notify": notify,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,14 +128,13 @@ namespace _heimdall.notification_kinds.email
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function notification_kind_implementation(
|
register_implementation(
|
||||||
) : type_notification_kind
|
"email",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"notify": notify,
|
"notify": notify,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,14 +114,13 @@ namespace _heimdall.notification_kinds.libnotify
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function notification_kind_implementation(
|
register_implementation(
|
||||||
) : type_notification_kind
|
"libnotify",
|
||||||
{
|
{
|
||||||
return {
|
|
||||||
"parameters_schema": parameters_schema,
|
"parameters_schema": parameters_schema,
|
||||||
"normalize_order_node": normalize_order_node,
|
"normalize_order_node": normalize_order_node,
|
||||||
"notify": notify,
|
"notify": notify,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,9 @@ namespace _heimdall.order
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function schema_notifications(
|
function schema_notifications(
|
||||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>
|
|
||||||
) : _heimdall.helpers.json_schema.type_schema
|
) : _heimdall.helpers.json_schema.type_schema
|
||||||
{
|
{
|
||||||
|
const notification_kind_implementations = _heimdall.notification_kinds.get_implementations();
|
||||||
return {
|
return {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
|
@ -149,10 +149,9 @@ namespace _heimdall.order
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function schema_root(
|
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
|
) : _heimdall.helpers.json_schema.type_schema
|
||||||
{
|
{
|
||||||
|
const check_kind_implementations = _heimdall.check_kinds.get_implementations();
|
||||||
return {
|
return {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|
@ -166,7 +165,7 @@ namespace _heimdall.order
|
||||||
"threshold": schema_threshold(),
|
"threshold": schema_threshold(),
|
||||||
"annoy": schema_annoy(),
|
"annoy": schema_annoy(),
|
||||||
"schedule": schema_schedule(),
|
"schedule": schema_schedule(),
|
||||||
"notifications": schema_notifications(notification_kind_implementations),
|
"notifications": schema_notifications(),
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
],
|
],
|
||||||
|
|
@ -198,7 +197,7 @@ namespace _heimdall.order
|
||||||
"threshold": schema_threshold(),
|
"threshold": schema_threshold(),
|
||||||
"annoy": schema_annoy(),
|
"annoy": schema_annoy(),
|
||||||
"schedule": schema_schedule(),
|
"schedule": schema_schedule(),
|
||||||
"notifications": schema_notifications(notification_kind_implementations),
|
"notifications": schema_notifications(),
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"name",
|
"name",
|
||||||
|
|
@ -301,10 +300,10 @@ namespace _heimdall.order
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function normalize_notification(
|
function normalize_notification(
|
||||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
|
||||||
node : any
|
node : any
|
||||||
) : type_notification
|
) : type_notification
|
||||||
{
|
{
|
||||||
|
const notification_kind_implementations = _heimdall.notification_kinds.get_implementations();
|
||||||
if (! (node["kind"] in notification_kind_implementations)) {
|
if (! (node["kind"] in notification_kind_implementations)) {
|
||||||
throw new Error("invalid notification kind: " + node["kind"]);
|
throw new Error("invalid notification kind: " + node["kind"]);
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +319,6 @@ namespace _heimdall.order
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function normalize_defaults(
|
function normalize_defaults(
|
||||||
notification_kind_implementations : Record<string, _heimdall.notification_kinds.type_notification_kind>,
|
|
||||||
node : any
|
node : any
|
||||||
) : type_check_common
|
) : type_check_common
|
||||||
{
|
{
|
||||||
|
|
@ -346,7 +344,7 @@ namespace _heimdall.order
|
||||||
"schedule": node_["schedule"],
|
"schedule": node_["schedule"],
|
||||||
"notifications": (
|
"notifications": (
|
||||||
node_["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(
|
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,
|
defaults : type_check_common,
|
||||||
node : {
|
node : {
|
||||||
name : string;
|
name : string;
|
||||||
|
|
@ -364,6 +360,8 @@ namespace _heimdall.order
|
||||||
}
|
}
|
||||||
) : type_check
|
) : type_check
|
||||||
{
|
{
|
||||||
|
const check_kind_implementations = _heimdall.check_kinds.get_implementations();
|
||||||
|
const notification_kind_implementations = _heimdall.notification_kinds.get_implementations();
|
||||||
if (! ("name" in node)) {
|
if (! ("name" in node)) {
|
||||||
throw new Error("missing mandatory field in 'check' node: 'name'");
|
throw new Error("missing mandatory field in 'check' node: 'name'");
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +408,7 @@ namespace _heimdall.order
|
||||||
check.notifications = (
|
check.notifications = (
|
||||||
node_["notifications"]
|
node_["notifications"]
|
||||||
.map(
|
.map(
|
||||||
x => normalize_notification(notification_kind_implementations, x),
|
x => normalize_notification(x),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -427,8 +425,6 @@ namespace _heimdall.order
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function normalize_root(
|
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,
|
node : any,
|
||||||
options : {
|
options : {
|
||||||
use_implicit_default_values ?: boolean;
|
use_implicit_default_values ?: boolean;
|
||||||
|
|
@ -440,7 +436,8 @@ namespace _heimdall.order
|
||||||
"use_implicit_default_values": true,
|
"use_implicit_default_values": true,
|
||||||
},
|
},
|
||||||
options
|
options
|
||||||
)
|
);
|
||||||
|
|
||||||
let counts : Record<string, int> = {};
|
let counts : Record<string, int> = {};
|
||||||
const checks_raw : Array<any> = (
|
const checks_raw : Array<any> = (
|
||||||
("checks" in node)
|
("checks" in node)
|
||||||
|
|
@ -480,7 +477,6 @@ namespace _heimdall.order
|
||||||
const defaults : type_check_common = (
|
const defaults : type_check_common = (
|
||||||
options.use_implicit_default_values
|
options.use_implicit_default_values
|
||||||
? normalize_defaults(
|
? normalize_defaults(
|
||||||
notification_kind_implementations,
|
|
||||||
defaults_raw
|
defaults_raw
|
||||||
)
|
)
|
||||||
: defaults_raw
|
: defaults_raw
|
||||||
|
|
@ -497,8 +493,6 @@ namespace _heimdall.order
|
||||||
checks_raw
|
checks_raw
|
||||||
.map(
|
.map(
|
||||||
node_ => normalize_check(
|
node_ => normalize_check(
|
||||||
check_kind_implementations,
|
|
||||||
notification_kind_implementations,
|
|
||||||
defaults,
|
defaults,
|
||||||
node_
|
node_
|
||||||
)
|
)
|
||||||
|
|
@ -512,8 +506,6 @@ namespace _heimdall.order
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function load(
|
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,
|
path : string,
|
||||||
options : {
|
options : {
|
||||||
root ?: boolean;
|
root ?: boolean;
|
||||||
|
|
@ -529,7 +521,8 @@ namespace _heimdall.order
|
||||||
"already_included": [],
|
"already_included": [],
|
||||||
},
|
},
|
||||||
options
|
options
|
||||||
)
|
);
|
||||||
|
|
||||||
if (options.already_included.includes(path)) {
|
if (options.already_included.includes(path)) {
|
||||||
throw new Error("circular dependency detected")
|
throw new Error("circular dependency detected")
|
||||||
}
|
}
|
||||||
|
|
@ -546,8 +539,6 @@ namespace _heimdall.order
|
||||||
for (let index = 0; index < includes.length; index += 1) {
|
for (let index = 0; index < includes.length; index += 1) {
|
||||||
const path_ : string = includes[index];
|
const path_ : string = includes[index];
|
||||||
const sub_order : type_order = await load(
|
const sub_order : type_order = await load(
|
||||||
check_kind_implementations,
|
|
||||||
notification_kind_implementations,
|
|
||||||
(
|
(
|
||||||
nm_path.isAbsolute(path_)
|
nm_path.isAbsolute(path_)
|
||||||
? path_
|
? path_
|
||||||
|
|
@ -582,8 +573,6 @@ namespace _heimdall.order
|
||||||
order_raw.includes = [];
|
order_raw.includes = [];
|
||||||
}
|
}
|
||||||
return normalize_root(
|
return normalize_root(
|
||||||
check_kind_implementations,
|
|
||||||
notification_kind_implementations,
|
|
||||||
order_raw,
|
order_raw,
|
||||||
{
|
{
|
||||||
"use_implicit_default_values": options["root"],
|
"use_implicit_default_values": options["root"],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
namespace _heimdall.state_repository
|
namespace _heimdall.state_repository
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
var _connection : (null | lib_plankton.sqlite.type_connection) = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
function condition_decode(
|
function condition_decode(
|
||||||
|
|
@ -33,12 +38,32 @@ namespace _heimdall.state_repository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function setup(
|
export async function init(
|
||||||
database_path : string
|
database_path : string
|
||||||
) : Promise<void>
|
) : Promise<void>
|
||||||
{
|
{
|
||||||
const result = await _heimdall.helpers.sqlite.query_set(
|
_connection = await lib_plankton.sqlite.get_connection(database_path);
|
||||||
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);",
|
"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": {
|
"arguments": {
|
||||||
|
|
@ -51,13 +76,12 @@ namespace _heimdall.state_repository
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function clean(
|
export async function clean(
|
||||||
database_path : string,
|
|
||||||
time_to_live : int,
|
time_to_live : int,
|
||||||
erase_state : boolean
|
erase_state : boolean
|
||||||
) : Promise<int>
|
) : Promise<int>
|
||||||
{
|
{
|
||||||
const result = await _heimdall.helpers.sqlite.query_put(
|
const result = await lib_plankton.sqlite.query_put(
|
||||||
database_path,
|
_connection,
|
||||||
{
|
{
|
||||||
"template": "DELETE FROM results WHERE ((timestamp < :timestamp_min) OR :erase_state);",
|
"template": "DELETE FROM results WHERE ((timestamp < :timestamp_min) OR :erase_state);",
|
||||||
"arguments": {
|
"arguments": {
|
||||||
|
|
@ -73,7 +97,6 @@ namespace _heimdall.state_repository
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function probe(
|
export async function probe(
|
||||||
database_path : string,
|
|
||||||
check_name : string,
|
check_name : string,
|
||||||
threshold : int
|
threshold : int
|
||||||
) : Promise<
|
) : Promise<
|
||||||
|
|
@ -86,8 +109,8 @@ namespace _heimdall.state_repository
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
const rows : Array<Array<any>> = await _heimdall.helpers.sqlite.query_get(
|
const rows : Array<Record<string, any>> = await lib_plankton.sqlite.query_get(
|
||||||
database_path,
|
_connection,
|
||||||
{
|
{
|
||||||
"template": "SELECT timestamp, condition, notification_sent FROM results WHERE (check_name = :check_name) ORDER BY timestamp DESC LIMIT :limit;",
|
"template": "SELECT timestamp, condition, notification_sent FROM results WHERE (check_name = :check_name) ORDER BY timestamp DESC LIMIT :limit;",
|
||||||
"arguments": {
|
"arguments": {
|
||||||
|
|
@ -100,9 +123,9 @@ namespace _heimdall.state_repository
|
||||||
rows
|
rows
|
||||||
.map(
|
.map(
|
||||||
row => ({
|
row => ({
|
||||||
"timestamp": row[0],
|
"timestamp": row["timestamp"],
|
||||||
"condition": condition_decode(row[1]),
|
"condition": condition_decode(row["condition"]),
|
||||||
"notification_sent": row[2],
|
"notification_sent": row["notification_sent"],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
@ -112,27 +135,25 @@ namespace _heimdall.state_repository
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function get_last_notification_timestamp(
|
export async function get_last_notification_timestamp(
|
||||||
database_path : string,
|
|
||||||
check_name : string
|
check_name : string
|
||||||
) : Promise<(null | int)>
|
) : Promise<(null | int)>
|
||||||
{
|
{
|
||||||
const rows : Array<Array<any>> = await _heimdall.helpers.sqlite.query_get(
|
const rows : Array<Record<string, any>> = await lib_plankton.sqlite.query_get(
|
||||||
database_path,
|
_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": {
|
"arguments": {
|
||||||
"check_name": check_name,
|
"check_name": check_name,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return rows[0][0];
|
return rows[0]["max_timestamp"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export async function feed(
|
export async function feed(
|
||||||
database_path : string,
|
|
||||||
check_name : string,
|
check_name : string,
|
||||||
timestamp : int,
|
timestamp : int,
|
||||||
condition : _heimdall.enum_condition,
|
condition : _heimdall.enum_condition,
|
||||||
|
|
@ -140,8 +161,8 @@ namespace _heimdall.state_repository
|
||||||
info : any
|
info : any
|
||||||
) : Promise<void>
|
) : Promise<void>
|
||||||
{
|
{
|
||||||
await _heimdall.helpers.sqlite.query_put(
|
await lib_plankton.sqlite.query_put(
|
||||||
database_path,
|
_connection,
|
||||||
{
|
{
|
||||||
"template": "INSERT INTO results(check_name, timestamp, condition, notification_sent, info) VALUES (:check_name, :timestamp, :condition, :notification_sent, :info);",
|
"template": "INSERT INTO results(check_name, timestamp, condition, notification_sent, info) VALUES (:check_name, :timestamp, :condition, :notification_sent, :info);",
|
||||||
"arguments": {
|
"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)
|
- Benachrichtigungen versenden, wenn ein Zustand sich wieder normalisiert hat (aber vorher über dem Schwellwert oft nicht OK war)
|
||||||
- Selbst-Test
|
- Selbst-Test
|
||||||
- Benachrichtigungs-Kanäle:
|
- Benachrichtigungs-Kanäle:
|
||||||
|
|
|
||||||
21
tools/build
21
tools/build
|
|
@ -2,13 +2,24 @@
|
||||||
|
|
||||||
## vars
|
## vars
|
||||||
|
|
||||||
path_prj_from=tools/heimdall.prj.json
|
path_prj_core_from=tools/heimdall-core.prj.json
|
||||||
path_prj_to=heimdall.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
|
## exec
|
||||||
|
|
||||||
cp ${path_prj_from} ${path_prj_to}
|
cp ${path_prj_core_from} ${path_prj_core_to}
|
||||||
koralle --execute ${path_prj_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
|
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} translate"
|
||||||
modules="${modules} args"
|
modules="${modules} args"
|
||||||
modules="${modules} http"
|
modules="${modules} http"
|
||||||
|
modules="${modules} sqlite"
|
||||||
|
|
||||||
|
|
||||||
## exec
|
## exec
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue