4e vague de démockage des sondes
This commit is contained in:
parent
3397a00d42
commit
a64386db45
8 changed files with 208 additions and 18 deletions
|
|
@ -135,6 +135,41 @@ def main() -> int:
|
|||
|
||||
exit_with(2, f"CRITICAL - {args.label}: seuils incohérents")
|
||||
|
||||
elif args.probe_type == "current_value":
|
||||
if args.source_type != "manual_value":
|
||||
exit_with(2, f"CRITICAL - source_type non supporté: {args.source_type}")
|
||||
if args.unit not in {"%", "units", "litres", "volts", "watts"}:
|
||||
exit_with(2, f"CRITICAL - unité non supportée: {args.unit}")
|
||||
|
||||
if args.inputs_file and args.item_key:
|
||||
item = load_input_item(args.inputs_file, args.item_key)
|
||||
metric = float(str(item.get("value", "")).strip())
|
||||
elif args.source_value:
|
||||
metric = float(str(args.source_value).strip())
|
||||
else:
|
||||
raise ValueError("manual_value exige inputs-file/item-key ou source-value")
|
||||
|
||||
unit_suffix = args.unit
|
||||
|
||||
if args.critical_lt is not None and metric < args.critical_lt:
|
||||
exit_with(2, f"CRITICAL - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
if args.critical_gte is not None and metric >= args.critical_gte:
|
||||
exit_with(2, f"CRITICAL - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
if args.warning_lt is not None and metric < args.warning_lt:
|
||||
exit_with(1, f"WARNING - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
if args.warning_gte is not None and metric >= args.warning_gte:
|
||||
exit_with(1, f"WARNING - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
if args.ok_gte is not None and metric >= args.ok_gte:
|
||||
exit_with(0, f"OK - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
if args.ok_lt is not None and metric < args.ok_lt:
|
||||
exit_with(0, f"OK - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
if args.unknown_gte is not None and metric >= args.unknown_gte:
|
||||
exit_with(3, f"UNKNOWN - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
if args.unknown_lt is not None and metric < args.unknown_lt:
|
||||
exit_with(3, f"UNKNOWN - {args.label}: {metric:.1f} {unit_suffix}")
|
||||
|
||||
exit_with(2, f"CRITICAL - {args.label}: seuils incohérents")
|
||||
|
||||
else:
|
||||
exit_with(2, f"CRITICAL - probe_type non supporté: {args.probe_type}")
|
||||
|
||||
|
|
|
|||
72
domains.yaml
72
domains.yaml
|
|
@ -1014,6 +1014,24 @@ domains:
|
|||
- name: verification-tension-batteries
|
||||
date: 2026-03-15
|
||||
notes: Vérification des tensions et cohérence des batteries
|
||||
probe:
|
||||
type: current_value
|
||||
source:
|
||||
type: manual_value
|
||||
inputs_file: /opt/life-noc/data/inputs/energie.yaml
|
||||
item_key: verification-tension-batteries
|
||||
metric:
|
||||
unit: volts
|
||||
thresholds:
|
||||
critical_lt: 50.0
|
||||
warning_lt: 51.2
|
||||
ok_gte: 51.2
|
||||
policy:
|
||||
on_error: critical
|
||||
ui:
|
||||
form_mode: numeric_value
|
||||
allow_complete: false
|
||||
allow_manual_edit: true
|
||||
- name: verification-smartshunt
|
||||
date: 2026-03-15
|
||||
notes: Vérification SmartShunt et cohérence du monitoring
|
||||
|
|
@ -1650,6 +1668,24 @@ domains:
|
|||
- name: verification-batterie-voiture
|
||||
date: 2026-10-01
|
||||
notes: Vérification de l'état de la batterie automobile
|
||||
probe:
|
||||
type: current_value
|
||||
source:
|
||||
type: manual_value
|
||||
inputs_file: /opt/life-noc/data/inputs/voiture.yaml
|
||||
item_key: verification-batterie-voiture
|
||||
metric:
|
||||
unit: volts
|
||||
thresholds:
|
||||
critical_lt: 12.2
|
||||
warning_lt: 12.5
|
||||
ok_gte: 12.5
|
||||
policy:
|
||||
on_error: critical
|
||||
ui:
|
||||
form_mode: numeric_value
|
||||
allow_complete: false
|
||||
allow_manual_edit: true
|
||||
- name: verification-balais-essuie-glace
|
||||
date: 2026-05-01
|
||||
notes: Vérification des essuie-glaces
|
||||
|
|
@ -2244,9 +2280,45 @@ domains:
|
|||
- name: verification-ups-infrastructure
|
||||
date: 2026-04-15
|
||||
notes: Vérification des UPS de l'infrastructure
|
||||
probe:
|
||||
type: current_value
|
||||
source:
|
||||
type: manual_value
|
||||
inputs_file: /opt/life-noc/data/inputs/infrastructure-chezlepro.yaml
|
||||
item_key: verification-ups-infrastructure
|
||||
metric:
|
||||
unit: '%'
|
||||
thresholds:
|
||||
critical_lt: 25
|
||||
warning_lt: 50
|
||||
ok_gte: 50
|
||||
policy:
|
||||
on_error: critical
|
||||
ui:
|
||||
form_mode: numeric_value
|
||||
allow_complete: false
|
||||
allow_manual_edit: true
|
||||
- name: verification-capacite-stockage
|
||||
date: 2026-04-15
|
||||
notes: Vérifier capacité et croissance du stockage
|
||||
probe:
|
||||
type: current_value
|
||||
source:
|
||||
type: manual_value
|
||||
inputs_file: /opt/life-noc/data/inputs/infrastructure-chezlepro.yaml
|
||||
item_key: verification-capacite-stockage
|
||||
metric:
|
||||
unit: '%'
|
||||
thresholds:
|
||||
critical_lt: 15
|
||||
warning_lt: 25
|
||||
ok_gte: 25
|
||||
policy:
|
||||
on_error: critical
|
||||
ui:
|
||||
form_mode: numeric_value
|
||||
allow_complete: false
|
||||
allow_manual_edit: true
|
||||
- name: verification-apt-cacher-ng
|
||||
date: 2026-05-01
|
||||
notes: Vérification du bon fonctionnement d'apt-cacher-ng
|
||||
|
|
|
|||
|
|
@ -25,11 +25,19 @@ apply Service "energie-inspection-batteries-lifepo4" {
|
|||
}
|
||||
|
||||
apply Service "energie-verification-tension-batteries" {
|
||||
import "service_echeance"
|
||||
vars.date_echeance = "2026-03-15"
|
||||
vars.mock_state = "OK"
|
||||
vars.mock_message = "Sous contrôle"
|
||||
import "service_life_noc_probe"
|
||||
vars.life_noc_probe_type = "current_value"
|
||||
vars.life_noc_source_type = "manual_value"
|
||||
vars.life_noc_source_value = ""
|
||||
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/energie.yaml"
|
||||
vars.life_noc_item_key = "verification-tension-batteries"
|
||||
vars.life_noc_metric_unit = "volts"
|
||||
vars.life_noc_label = "verification-tension-batteries"
|
||||
groups = [ "ENERGIE" ]
|
||||
vars.life_noc_threshold_ok_gte = "51.2"
|
||||
vars.life_noc_threshold_warning_lt = "51.2"
|
||||
vars.life_noc_threshold_critical_lt = "50.0"
|
||||
vars.life_noc_on_error = "critical"
|
||||
notes = "Vérification des tensions et cohérence des batteries"
|
||||
vars.instructions_url = "/life-noc/item/energie/verification-tension-batteries"
|
||||
assign where host.name == "life-noc"
|
||||
|
|
|
|||
|
|
@ -76,22 +76,38 @@ apply Service "infrastructure-chezlepro-verification-pbs-truenas" {
|
|||
}
|
||||
|
||||
apply Service "infrastructure-chezlepro-verification-ups-infrastructure" {
|
||||
import "service_echeance"
|
||||
vars.date_echeance = "2026-04-15"
|
||||
vars.mock_state = "OK"
|
||||
vars.mock_message = "Sous contrôle"
|
||||
import "service_life_noc_probe"
|
||||
vars.life_noc_probe_type = "current_value"
|
||||
vars.life_noc_source_type = "manual_value"
|
||||
vars.life_noc_source_value = ""
|
||||
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/infrastructure-chezlepro.yaml"
|
||||
vars.life_noc_item_key = "verification-ups-infrastructure"
|
||||
vars.life_noc_metric_unit = "%"
|
||||
vars.life_noc_label = "verification-ups-infrastructure"
|
||||
groups = [ "INFRASTRUCTURE-CHEZLEPRO" ]
|
||||
vars.life_noc_threshold_ok_gte = "50"
|
||||
vars.life_noc_threshold_warning_lt = "50"
|
||||
vars.life_noc_threshold_critical_lt = "25"
|
||||
vars.life_noc_on_error = "critical"
|
||||
notes = "Vérification des UPS de l'infrastructure"
|
||||
vars.instructions_url = "/life-noc/item/infrastructure-chezlepro/verification-ups-infrastructure"
|
||||
assign where host.name == "life-noc"
|
||||
}
|
||||
|
||||
apply Service "infrastructure-chezlepro-verification-capacite-stockage" {
|
||||
import "service_echeance"
|
||||
vars.date_echeance = "2026-04-15"
|
||||
vars.mock_state = "OK"
|
||||
vars.mock_message = "Sous contrôle"
|
||||
import "service_life_noc_probe"
|
||||
vars.life_noc_probe_type = "current_value"
|
||||
vars.life_noc_source_type = "manual_value"
|
||||
vars.life_noc_source_value = ""
|
||||
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/infrastructure-chezlepro.yaml"
|
||||
vars.life_noc_item_key = "verification-capacite-stockage"
|
||||
vars.life_noc_metric_unit = "%"
|
||||
vars.life_noc_label = "verification-capacite-stockage"
|
||||
groups = [ "INFRASTRUCTURE-CHEZLEPRO" ]
|
||||
vars.life_noc_threshold_ok_gte = "25"
|
||||
vars.life_noc_threshold_warning_lt = "25"
|
||||
vars.life_noc_threshold_critical_lt = "15"
|
||||
vars.life_noc_on_error = "critical"
|
||||
notes = "Vérifier capacité et croissance du stockage"
|
||||
vars.instructions_url = "/life-noc/item/infrastructure-chezlepro/verification-capacite-stockage"
|
||||
assign where host.name == "life-noc"
|
||||
|
|
|
|||
|
|
@ -96,11 +96,19 @@ apply Service "voiture-verification-timing-belt" {
|
|||
}
|
||||
|
||||
apply Service "voiture-verification-batterie-voiture" {
|
||||
import "service_echeance"
|
||||
vars.date_echeance = "2026-10-01"
|
||||
vars.mock_state = "OK"
|
||||
vars.mock_message = "Sous contrôle"
|
||||
import "service_life_noc_probe"
|
||||
vars.life_noc_probe_type = "current_value"
|
||||
vars.life_noc_source_type = "manual_value"
|
||||
vars.life_noc_source_value = ""
|
||||
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/voiture.yaml"
|
||||
vars.life_noc_item_key = "verification-batterie-voiture"
|
||||
vars.life_noc_metric_unit = "volts"
|
||||
vars.life_noc_label = "verification-batterie-voiture"
|
||||
groups = [ "VOITURE" ]
|
||||
vars.life_noc_threshold_ok_gte = "12.5"
|
||||
vars.life_noc_threshold_warning_lt = "12.5"
|
||||
vars.life_noc_threshold_critical_lt = "12.2"
|
||||
vars.life_noc_on_error = "critical"
|
||||
notes = "Vérification de l'état de la batterie automobile"
|
||||
vars.instructions_url = "/life-noc/item/voiture/verification-batterie-voiture"
|
||||
assign where host.name == "life-noc"
|
||||
|
|
|
|||
|
|
@ -194,4 +194,30 @@ def compute_state_for_item(domain: str, item_key: str) -> str:
|
|||
return "UNKNOWN"
|
||||
return "CRITICAL"
|
||||
|
||||
if probe_type == "current_value":
|
||||
if source_type != "manual_value":
|
||||
return "CRITICAL"
|
||||
if metric_unit not in {"%", "units", "litres", "volts", "watts"}:
|
||||
return "CRITICAL"
|
||||
|
||||
value = float(str(item.get("value", "")).strip())
|
||||
|
||||
if "critical_lt" in thresholds and value < float(thresholds["critical_lt"]):
|
||||
return "CRITICAL"
|
||||
if "critical_gte" in thresholds and value >= float(thresholds["critical_gte"]):
|
||||
return "CRITICAL"
|
||||
if "warning_lt" in thresholds and value < float(thresholds["warning_lt"]):
|
||||
return "WARNING"
|
||||
if "warning_gte" in thresholds and value >= float(thresholds["warning_gte"]):
|
||||
return "WARNING"
|
||||
if "ok_gte" in thresholds and value >= float(thresholds["ok_gte"]):
|
||||
return "OK"
|
||||
if "ok_lt" in thresholds and value < float(thresholds["ok_lt"]):
|
||||
return "OK"
|
||||
if "unknown_gte" in thresholds and value >= float(thresholds["unknown_gte"]):
|
||||
return "UNKNOWN"
|
||||
if "unknown_lt" in thresholds and value < float(thresholds["unknown_lt"]):
|
||||
return "UNKNOWN"
|
||||
return "CRITICAL"
|
||||
|
||||
return "CRITICAL"
|
||||
|
|
|
|||
|
|
@ -202,8 +202,8 @@ def validate_probe(item: dict) -> None:
|
|||
raise ValueError("probe doit être un objet")
|
||||
|
||||
probe_type = str(probe.get("type", "")).strip()
|
||||
if probe_type not in {"elapsed_time", "days_until_due", "elapsed_distance", "remaining_quantity"}:
|
||||
raise ValueError("seuls probe.type=elapsed_time, days_until_due, elapsed_distance et remaining_quantity sont supportés")
|
||||
if probe_type not in {"elapsed_time", "days_until_due", "elapsed_distance", "remaining_quantity", "current_value"}:
|
||||
raise ValueError("seuls probe.type=elapsed_time, days_until_due, elapsed_distance, remaining_quantity et current_value sont supportés")
|
||||
|
||||
source = probe.get("source")
|
||||
if not isinstance(source, dict):
|
||||
|
|
@ -228,6 +228,11 @@ def validate_probe(item: dict) -> None:
|
|||
raise ValueError("seul probe.source.type=manual_value est supporté pour remaining_quantity")
|
||||
if not has_store_ref:
|
||||
raise ValueError("probe.source.inputs_file + item_key requis pour remaining_quantity")
|
||||
elif probe_type == "current_value":
|
||||
if source_type != "manual_value":
|
||||
raise ValueError("seul probe.source.type=manual_value est supporté pour current_value")
|
||||
if not has_store_ref:
|
||||
raise ValueError("probe.source.inputs_file + item_key requis pour current_value")
|
||||
|
||||
metric = probe.get("metric")
|
||||
if not isinstance(metric, dict):
|
||||
|
|
@ -239,6 +244,8 @@ def validate_probe(item: dict) -> None:
|
|||
raise ValueError("seul probe.metric.unit=km est supporté pour elapsed_distance")
|
||||
if probe_type == "remaining_quantity" and metric_unit not in {"%", "units", "litres"}:
|
||||
raise ValueError("probe.metric.unit doit être %, units ou litres pour remaining_quantity")
|
||||
if probe_type == "current_value" and metric_unit not in {"%", "units", "litres", "volts", "watts"}:
|
||||
raise ValueError("probe.metric.unit doit être %, units, litres, volts ou watts pour current_value")
|
||||
|
||||
thresholds = probe.get("thresholds")
|
||||
if not isinstance(thresholds, dict):
|
||||
|
|
|
|||
|
|
@ -663,6 +663,24 @@ def page_item(domain: str, item_key: str) -> HTMLResponse:
|
|||
</form>
|
||||
</section>
|
||||
"""
|
||||
elif allow_manual_edit and form_mode == "numeric_value":
|
||||
unit = str(service.get("probe", {}).get("metric", {}).get("unit", "")).strip()
|
||||
unit_hint = f" ({html_escape(unit)})" if unit else ""
|
||||
manual_form_html = f"""
|
||||
<section class="card">
|
||||
<h2>Mettre à jour la valeur</h2>
|
||||
<p class="muted">Saisir la valeur observée{unit_hint}.</p>
|
||||
<form method="post" action="/life-noc/item/{html_escape(domain)}/{html_escape(item_key)}/set" class="form-grid">
|
||||
<label>Valeur courante{unit_hint}
|
||||
<input type="text" inputmode="decimal" name="value" value="{html_escape(current_input.get('value', ''))}" required>
|
||||
</label>
|
||||
<input type="hidden" name="origin" value="manual">
|
||||
<div class="actions">
|
||||
<button type="submit">Enregistrer</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
"""
|
||||
|
||||
complete_form_html = ""
|
||||
if allow_complete:
|
||||
|
|
|
|||
Loading…
Reference in a new issue