/* Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »heimdall« is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »heimdall« 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 General Public License for more details. You should have received a copy of the GNU General Public License along with »heimdall«. If not, see . */ namespace _heimdall.check_kinds.file_state { /** */ function parameters_schema( ) : _heimdall.helpers.json_schema.type_schema { return { "type": "object", "additionalProperties": false, "properties": { "path": { "type": "string" }, "exist_mode": { "description": "whether the file is supposed to exist or not", "type": "boolean", "default": true, }, "exist_critical": { "description": "whether a violation of the extist state (parameter 'exist_mode') shall be considered as critical (true) or concerning (false)", "type": "boolean", "default": true, }, "age_threshold_concerning": { "description": "in seconds; ignored if 'exist_mode' is set to false", "anyOf": [ { "type": "null", }, { "type": "integer", "exclusiveMinimum": 0, }, ], "default": null, }, "age_threshold_critical": { "description": "in seconds; ignored if 'exist_mode' is set to false", "anyOf": [ { "type": "null", }, { "type": "integer", "exclusiveMinimum": 0, }, ], "default": null, }, "size_threshold_concerning": { "description": "in bytes; ignored if 'exist_mode' is set to false", "anyOf": [ { "type": "null", }, { "type": "integer", "exclusiveMinimum": 0, }, ], "default": null, }, "size_threshold_critical": { "description": "in bytes; ignored if 'exist_mode' is set to false", "anyOf": [ { "type": "null", }, { "type": "integer", "exclusiveMinimum": 0, }, ], "default": null, }, // deprecated "strict": { "deprecated": true, "description": "", "type": "boolean", "default": true, }, "exist": { "deprecated": true, "description": "", "type": "boolean", "default": true, }, "age_threshold": { "deprecated": true, "description": "", "anyOf": [ { "type": "null", }, { "type": "integer", "exclusiveMinimum": 0, }, ], "default": null, }, "size_threshold": { "deprecated": true, "description": "", "anyOf": [ { "type": "null", }, { "type": "integer", "exclusiveMinimum": 0, }, ], "default": null, }, }, "required": [ "path", ] }; } /** */ function normalize_order_node( node : any ) : any { const version : string = ( (! ("exist_mode" in node)) ? "v1" : "v2" ); switch (version) { default: { throw (new Error("unhandled version")); break; } case "v1": { if (! ("path" in node)) { throw new Error("missing mandatory field 'path'"); } else { const node_ = Object.assign( { "strict": true, "exist": true, "age_threshold": null, "size_threshold": null, }, node ); return { "path": node["path"], "exist_mode": node_["exist"], "exist_critical": node_["strict"], "age_threshold_concerning": ( node_["strict"] ? null : node_["age_threshold"] ), "age_threshold_critical": ( node_["strict"] ? node_["age_threshold"] : null ), "size_threshold_concerning": ( node_["strict"] ? null : node_["age_threshold"] ), "size_threshold_critical": ( node_["strict"] ? node_["age_threshold"] : null ), }; } break; } case "v2": { if (! ("path" in node)) { throw new Error("missing mandatory field 'path'"); } else { const node_ = Object.assign( { "exist_mode": true, "exist_critical": true, "age_threshold_concerning": null, "age_threshold_critical": null, "size_threshold_concerning": null, "size_threshold_critical": null, }, node ); return node_; } break; } } } /** */ async function run( parameters ) : Promise<_heimdall.type_result> { const nm_fs = require("fs"); let condition : _heimdall.enum_condition = _heimdall.enum_condition.ok; let faults : Array = []; let data : Record = {}; let exists : boolean; let stats : { ctime : float; size : int; }; await new Promise( (resolve, reject) => { nm_fs.stat( parameters["path"], { "bigint": false, }, (err, stats_) => { if (err) { exists = false; stats = null; resolve(undefined); } else { exists = true; stats = stats_; resolve(undefined); } } ); } ); if (! parameters["exist_mode"]) { if (exists) { condition = ( parameters["exist_critical"] ? _heimdall.enum_condition.concerning : _heimdall.enum_condition.critical ); faults.push(lib_plankton.translate.get("checks.file_state.exists")); } else { // do nothing } } else { if (! exists) { condition = ( parameters["exist_critical"] ? _heimdall.enum_condition.concerning : _heimdall.enum_condition.critical ); faults.push(lib_plankton.translate.get("checks.file_state.missing")); } else { // age { const timestamp_this : int = _heimdall.get_current_timestamp(); const timestamp_that : int = Math.floor(stats.ctime); const age : int = (timestamp_this - timestamp_that); if (age < 0) { condition = _heimdall.enum_condition.critical; faults.push(lib_plankton.translate.get("checks.file_state.timestamp_implausible")); } else { if ( (parameters["age_threshold_critical"] !== null) && (age > parameters["age_threshold_critical"]) ) { condition = _heimdall.enum_condition.critical; faults.push(lib_plankton.translate.get("checks.file_state.too_old")); } else { if ( (parameters["age_threshold_concerning"] !== null) && (age > parameters["age_threshold_concerning"]) ) { condition = _heimdall.enum_condition.critical; faults.push(lib_plankton.translate.get("checks.file_state.too_old")); } else { // do nothing } } } data = Object.assign( data, { "timestamp_of_checking_instance": timestamp_this, "timestamp_of_file": timestamp_that, "age_value_in_seconds": age, "age_threshold_in_seconds_concerning": parameters["age_threshold_concerning"], "age_threshold_in_seconds_critical": parameters["age_threshold_critical"], } ); } // size { const size : int = stats.size; if (size < 0) { condition = _heimdall.enum_condition.critical; faults.push(lib_plankton.translate.get("checks.file_state.size_implausible")); } else { if ( (parameters["size_threshold_critical"] !== null) && (size > parameters["size_threshold_critical"]) ) { condition = _heimdall.enum_condition.critical; faults.push(lib_plankton.translate.get("checks.file_state.too_big")); } else { if ( (parameters["size_threshold_concerning"] !== null) && (size > parameters["size_threshold_concerning"]) ) { condition = _heimdall.enum_condition.critical; faults.push(lib_plankton.translate.get("checks.file_state.too_big")); } else { // do nothing } } } data = Object.assign( data, { "size_value_in_bytes": size, "size_threshold_in_bytes": parameters["size_threshold"], } ); } } } return { "condition": condition, "info": { "path": parameters["path"], "faults": faults, "data": data, } }; } /** */ register_implementation( "file_state", { "parameters_schema": parameters_schema, "normalize_order_node": normalize_order_node, "run": run, } ); }