Ajoute un store d’intrants pour les sondes elapsed_time
This commit is contained in:
parent
aa3ebf3294
commit
febdc502c4
6 changed files with 69 additions and 10 deletions
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
def exit_with(code: int, text: str) -> None:
|
def exit_with(code: int, text: str) -> None:
|
||||||
|
|
@ -13,11 +16,35 @@ def parse_date(value: str) -> datetime:
|
||||||
return datetime.strptime(value, "%Y-%m-%d").replace(tzinfo=timezone.utc)
|
return datetime.strptime(value, "%Y-%m-%d").replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
|
def load_input_value(inputs_file: str, item_key: str) -> str:
|
||||||
|
path = Path(inputs_file)
|
||||||
|
if not path.exists():
|
||||||
|
raise ValueError(f"inputs file introuvable: {inputs_file}")
|
||||||
|
|
||||||
|
data = yaml.safe_load(path.read_text(encoding="utf-8"))
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
raise ValueError(f"inputs file invalide: {inputs_file}")
|
||||||
|
|
||||||
|
if item_key not in data:
|
||||||
|
raise ValueError(f"item_key introuvable dans le store: {item_key}")
|
||||||
|
|
||||||
|
item = data[item_key]
|
||||||
|
if not isinstance(item, dict):
|
||||||
|
raise ValueError(f"entrée invalide pour item_key: {item_key}")
|
||||||
|
|
||||||
|
if "value" not in item:
|
||||||
|
raise ValueError(f"champ 'value' absent pour item_key: {item_key}")
|
||||||
|
|
||||||
|
return str(item["value"]).strip()
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
ap = argparse.ArgumentParser()
|
ap = argparse.ArgumentParser()
|
||||||
ap.add_argument("--probe-type", required=True)
|
ap.add_argument("--probe-type", required=True)
|
||||||
ap.add_argument("--source-type", required=True)
|
ap.add_argument("--source-type", required=True)
|
||||||
ap.add_argument("--source-value", required=True)
|
ap.add_argument("--source-value")
|
||||||
|
ap.add_argument("--inputs-file")
|
||||||
|
ap.add_argument("--item-key")
|
||||||
ap.add_argument("--unit", required=True)
|
ap.add_argument("--unit", required=True)
|
||||||
ap.add_argument("--unknown-lt", type=float)
|
ap.add_argument("--unknown-lt", type=float)
|
||||||
ap.add_argument("--ok-gte", type=float)
|
ap.add_argument("--ok-gte", type=float)
|
||||||
|
|
@ -37,7 +64,16 @@ def main() -> int:
|
||||||
if args.unit != "days":
|
if args.unit != "days":
|
||||||
exit_with(2, f"CRITICAL - unité non supportée: {args.unit}")
|
exit_with(2, f"CRITICAL - unité non supportée: {args.unit}")
|
||||||
|
|
||||||
dt = parse_date(args.source_value)
|
source_value = None
|
||||||
|
|
||||||
|
if args.inputs_file and args.item_key:
|
||||||
|
source_value = load_input_value(args.inputs_file, args.item_key)
|
||||||
|
elif args.source_value:
|
||||||
|
source_value = args.source_value
|
||||||
|
else:
|
||||||
|
raise ValueError("aucune source fournie: inputs-file/item-key ou source-value requis")
|
||||||
|
|
||||||
|
dt = parse_date(source_value)
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
delta_days = (now - dt).total_seconds() / 86400.0
|
delta_days = (now - dt).total_seconds() / 86400.0
|
||||||
|
|
||||||
|
|
|
||||||
9
data/inputs/revue.yaml
Normal file
9
data/inputs/revue.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
revue-quotidienne-life-noc:
|
||||||
|
value: "2026-03-14"
|
||||||
|
captured_at: "2026-03-14T08:00:00Z"
|
||||||
|
origin: manual
|
||||||
|
|
||||||
|
revue-hebdomadaire-priorites:
|
||||||
|
value: "2026-03-10"
|
||||||
|
captured_at: "2026-03-14T08:00:00Z"
|
||||||
|
origin: manual
|
||||||
|
|
@ -8,7 +8,8 @@ domains:
|
||||||
type: elapsed_time
|
type: elapsed_time
|
||||||
source:
|
source:
|
||||||
type: manual_date
|
type: manual_date
|
||||||
value: "2026-03-13"
|
inputs_file: "/opt/life-noc/data/inputs/revue.yaml"
|
||||||
|
item_key: "revue-quotidienne-life-noc"
|
||||||
metric:
|
metric:
|
||||||
unit: days
|
unit: days
|
||||||
thresholds:
|
thresholds:
|
||||||
|
|
@ -26,7 +27,8 @@ domains:
|
||||||
type: elapsed_time
|
type: elapsed_time
|
||||||
source:
|
source:
|
||||||
type: manual_date
|
type: manual_date
|
||||||
value: "2026-03-10"
|
inputs_file: "/opt/life-noc/data/inputs/revue.yaml"
|
||||||
|
item_key: "revue-hebdomadaire-priorites"
|
||||||
metric:
|
metric:
|
||||||
unit: days
|
unit: days
|
||||||
thresholds:
|
thresholds:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ object CheckCommand "check_life_noc_probe" {
|
||||||
"--probe-type" = "$life_noc_probe_type$"
|
"--probe-type" = "$life_noc_probe_type$"
|
||||||
"--source-type" = "$life_noc_source_type$"
|
"--source-type" = "$life_noc_source_type$"
|
||||||
"--source-value" = "$life_noc_source_value$"
|
"--source-value" = "$life_noc_source_value$"
|
||||||
|
"--inputs-file" = "$life_noc_inputs_file$"
|
||||||
|
"--item-key" = "$life_noc_item_key$"
|
||||||
"--unit" = "$life_noc_metric_unit$"
|
"--unit" = "$life_noc_metric_unit$"
|
||||||
"--unknown-lt" = "$life_noc_threshold_unknown_lt$"
|
"--unknown-lt" = "$life_noc_threshold_unknown_lt$"
|
||||||
"--ok-gte" = "$life_noc_threshold_ok_gte$"
|
"--ok-gte" = "$life_noc_threshold_ok_gte$"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ apply Service "revue-revue-quotidienne-life-noc" {
|
||||||
import "service_life_noc_probe"
|
import "service_life_noc_probe"
|
||||||
vars.life_noc_probe_type = "elapsed_time"
|
vars.life_noc_probe_type = "elapsed_time"
|
||||||
vars.life_noc_source_type = "manual_date"
|
vars.life_noc_source_type = "manual_date"
|
||||||
vars.life_noc_source_value = "2026-03-13"
|
vars.life_noc_source_value = ""
|
||||||
|
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/revue.yaml"
|
||||||
|
vars.life_noc_item_key = "revue-quotidienne-life-noc"
|
||||||
vars.life_noc_metric_unit = "days"
|
vars.life_noc_metric_unit = "days"
|
||||||
vars.life_noc_label = "revue-quotidienne-life-noc"
|
vars.life_noc_label = "revue-quotidienne-life-noc"
|
||||||
groups = [ "REVUE" ]
|
groups = [ "REVUE" ]
|
||||||
|
|
@ -25,7 +27,9 @@ apply Service "revue-revue-hebdomadaire-priorites" {
|
||||||
import "service_life_noc_probe"
|
import "service_life_noc_probe"
|
||||||
vars.life_noc_probe_type = "elapsed_time"
|
vars.life_noc_probe_type = "elapsed_time"
|
||||||
vars.life_noc_source_type = "manual_date"
|
vars.life_noc_source_type = "manual_date"
|
||||||
vars.life_noc_source_value = "2026-03-10"
|
vars.life_noc_source_value = ""
|
||||||
|
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/revue.yaml"
|
||||||
|
vars.life_noc_item_key = "revue-hebdomadaire-priorites"
|
||||||
vars.life_noc_metric_unit = "days"
|
vars.life_noc_metric_unit = "days"
|
||||||
vars.life_noc_label = "revue-hebdomadaire-priorites"
|
vars.life_noc_label = "revue-hebdomadaire-priorites"
|
||||||
groups = [ "REVUE" ]
|
groups = [ "REVUE" ]
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,9 @@ def render_probe_service(domain: str, group_name: str, item: dict) -> str:
|
||||||
f' import "{PROBE_TEMPLATE}"',
|
f' import "{PROBE_TEMPLATE}"',
|
||||||
f' vars.life_noc_probe_type = "{icinga_escape(probe_type)}"',
|
f' vars.life_noc_probe_type = "{icinga_escape(probe_type)}"',
|
||||||
f' vars.life_noc_source_type = "{icinga_escape(str(source["type"]).strip())}"',
|
f' vars.life_noc_source_type = "{icinga_escape(str(source["type"]).strip())}"',
|
||||||
f' vars.life_noc_source_value = "{icinga_escape(str(source["value"]).strip())}"',
|
f' vars.life_noc_source_value = "{icinga_escape(str(source.get("value", "")).strip())}"',
|
||||||
|
f' vars.life_noc_inputs_file = "{icinga_escape(str(source.get("inputs_file", "")).strip())}"',
|
||||||
|
f' vars.life_noc_item_key = "{icinga_escape(str(source.get("item_key", name)).strip())}"',
|
||||||
f' vars.life_noc_metric_unit = "{icinga_escape(str(metric["unit"]).strip())}"',
|
f' vars.life_noc_metric_unit = "{icinga_escape(str(metric["unit"]).strip())}"',
|
||||||
f' vars.life_noc_label = "{icinga_escape(name)}"',
|
f' vars.life_noc_label = "{icinga_escape(name)}"',
|
||||||
f' groups = [ "{icinga_escape(group_name)}" ]',
|
f' groups = [ "{icinga_escape(group_name)}" ]',
|
||||||
|
|
@ -173,8 +175,12 @@ def validate_probe(item: dict) -> None:
|
||||||
raise ValueError("probe.source doit être un objet")
|
raise ValueError("probe.source doit être un objet")
|
||||||
if str(source.get("type", "")).strip() != "manual_date":
|
if str(source.get("type", "")).strip() != "manual_date":
|
||||||
raise ValueError("seul probe.source.type=manual_date est supporté en v1")
|
raise ValueError("seul probe.source.type=manual_date est supporté en v1")
|
||||||
if "value" not in source:
|
|
||||||
raise ValueError("probe.source.value est requis")
|
has_inline_value = "value" in source
|
||||||
|
has_store_ref = "inputs_file" in source and "item_key" in source
|
||||||
|
|
||||||
|
if not has_inline_value and not has_store_ref:
|
||||||
|
raise ValueError("probe.source.value ou probe.source.inputs_file + item_key requis")
|
||||||
|
|
||||||
metric = probe.get("metric")
|
metric = probe.get("metric")
|
||||||
if not isinstance(metric, dict):
|
if not isinstance(metric, dict):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue